想象一下我有一个fishTank
班。此类将代表一个鱼缸,它的大小,在其中可以放置鱼的某些边界,在不能放置鱼的某些障碍,通过鱼缸的一些水流中移动鱼等。
class fishTank
{
private:
double length;
double height;
//And some more complex things that define a fish tank
public:
fishtank(double, double, ...);
}
现在我需要在鱼缸中添加鱼。宣告我的鱼类类别的适当方法是什么? (鱼代表一大群鱼)
fishTank
内,我一个人独享鱼是没有道理的。fishTank
的属性,鱼类中的所有内容都取决于鱼缸:如何在鱼缸中装载鱼取决于鱼缸的大小,鱼的移动方式取决于陷阱的大小和性质等。
我的第一个尝试是创建fish类,并将tank作为鱼构造函数中的参数传递。然后将鱼的矢量作为私人成员添加到水箱中:
class fish
{
private:
//All properties of fish
public:
fish(const fishTank& aTank, All other properties of fish);
}
class fishTank
{
private:
std::vector<fish> fishInTank;
//Same as before
public:
//Same as before;
}
这真的是实现我所需的正确方法吗?我只是认为这不是一个好的设计,我将需要鱼缸作为鱼的参数,然后将每条鱼添加到鱼缸中。这有道理吗?
这是实现诸如抽象鱼类之类的东西,还是在鱼缸内筑巢鱼的正确场所?
答案 0 :(得分:2)
说实话,就像吃Reeces一样,没有正确或正确的方法。我个人?鱼缸有一个鱼的载体,然后,如果鱼需要游泳一刻,我会在鱼缸上有游泳的方法。这将叫每条鱼并告诉他们游泳,将鱼缸作为其游泳方法的参数。像这样:
class FishTank;
class Fish {
public:
void swim(const FishTank* tank) {
}
};
class FishTank {
private:
std::vector<Fish> allFish;
public:
void tick() {
for(Fish& fish : allFish){
fish.swim(this);
}
}
};
确实有十二种方法可以解决这个问题。我建议您读一本书,其中涉及以下内容:Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (ISBN 10: 0201633612)
答案 1 :(得分:1)
鱼需要了解
的属性fishTank
然后,您可以考虑将fish
中的friend
设为fishTank
:
class fishTank
{
private:
friend fish;
std::vector<fish> fishInTank;
...
现在fish
的任何实例都可以访问private
的任何给定实例的所有fishTank
成员。
答案 2 :(得分:1)
您的Fish
类可以在FishTank
类中声明,甚至可以是受保护的或私有的。这将使在Fish
之外更难/无法使用。但是没有办法表明它只能是FishTank
的直接成员。
class FishTank {
private:
class Fish {
Fish(const Fishtank &parent);
…
};
std::vector<Fish> fishInTank;
在内部声明该类后,它自动成为FishTank
的朋友,并且可以访问坦克的所有成员,包括私人成员。
正如Paul Evans所指出的,您也可以使用friend
来达到后一种效果。如果Fish
是一个复杂的类,将使FishTank
类的声明混乱,最好将其保存在另一个头文件中,将很有帮助。如果您的Fish
曾经将鱼暴露在外面,则FishTank
至少需要宣布为公开;对于与Fish
进行交易的任何一方,如果要包含完整的FishTank
标头,也可能是一个负担。
您还可以使用命名空间来解释语义分组:
namespace fish_tank {
class Fish { … };
class Tank { … };
};
答案 3 :(得分:1)
这是我的方式:
class FishTank;
class Fish
{
protected:
FishTank* tank;
Fish(FishTank* t) { tank = t; };
public:
void swim();
friend class FishTank;
};
class FishTank
{
private:
std::vector<Fish*> allFish;
public:
Fish* AddFish() {
Fish* f = new Fish(this);
allFish.push_back(f);
return f;
}
void tick() {
for (Fish* fish : allFish) {
fish->swim();
}
}
friend class Fish;
};