C++循环类引用哲学



想象下一个问题。我想要一张班级地图。每个Map实例都包含一个位置列表。我还希望每个地点都知道拥有他的地图。(这会阻碍封装吗?(在Python中,我可以毫无问题地使用类型提示。我可以按任意顺序定义这两个类。

from __future__ import annotations
class Map:
def __init__(self):
self.locations: list[Location]
self.locations = []
class Location(self, ):
def __init__(self, owner: Map):
self.owner = owner

我想,这阻碍了封装。但在Python中,我们不都是成年人吗?这对我帮助很大。如果Location子级可以访问父级,则我可以更改Location中的某些内容,并且父级可以知道。

我可以在C++中使用这种设计吗?这是推荐的吗?孩子能有他父亲的名字吗?我可以在父类知道其子类的同时,声明知道其父类的子类吗?

我自己学过C++,从来没有读过。

在C++中这样做没有问题。您只需要转发声明map类或location类。

就封装而言,如果Location只是使用Map的公共接口,那么这并不是一个真正的问题。如果你想让Location而不是必须使用Map的公共接口,Map可以成为位置类的朋友,但在这种情况下,封装被违反了;不过这是个品味问题。关于这类事情,没有正确或错误的答案。

无论如何,下面的代码:

#include <vector>
class Location;  // <= this is a forward declaration.
class Map {
private:
std::vector<Location> locations_;
public:
void insertLocation(float longitude, float lattitude);
};
class Location {
private:
Map& parent_;
float longitude_;
float lattitude_;
public:
Location(Map& map, float longi = 0.0f, float lat = 0.0f) :
parent_(map), longitude_(longi), lattitude_(lat)
{}
};
void Map::insertLocation(float longitude, float lattitude) {
locations_.emplace_back(*this, longitude, lattitude);
}
int main(void) {
Map map;
map.insertLocation(10.0, 40.0);
return 0;
}

在C++中,类声明通常在标头中,类方法在.cpp文件中。这与Python不同。

一个重要的结果是,您可以将父标头包含在子.cpp文件中,反之亦然。因此,子类方法可以使用父声明,反之亦然。

最新更新