如何设计一个将永远是另一个班级成员的班级

想象一下我有一个fishTank班。此类将代表一个鱼缸,它的大小,在其中可以放置鱼的某些边界,在不能放置鱼的某些障碍,通过鱼缸的一些水流中移动鱼等。

class fishTank
{
private:
    double length;
    double height;
//And some more complex things that define a fish tank
public:
     fishtank(double,double,...);
}

现在我需要在鱼缸中添加鱼。宣告我的鱼类类别的适当方法是什么? (鱼代表一大群鱼)

  1. 我的鱼将永远放在fishTank内,我一个人独享鱼是没有道理的。
  2. 鱼需要了解fishTank的属性,鱼类中的所有内容都取决于鱼缸:如何在鱼缸中装载鱼取决于鱼缸的大小,鱼的移动方式取决于陷阱的大小和性质等。
  3. 同一缸中可以有很多不同种类的鱼。

我的第一个尝试是创建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;
}

这真的是实现我所需的正确方法吗?我只是认为这不是一个好的设计,我将需要鱼缸作为鱼的参数,然后将每条鱼添加到鱼缸中。这有道理吗?

这是实现诸如抽象鱼类之类的东西,还是在鱼缸内筑巢鱼的正确场所?

lzc333 回答:如何设计一个将永远是另一个班级成员的班级

说实话,就像吃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)

,
  

鱼需要了解fishTank

的属性

然后,您可以考虑将fish中的friend设为fishTank

class fishTank
{
private:
    friend fish;
    std::vector<fish> fishInTank;
...

现在fish的任何实例都可以访问private的任何给定实例的所有fishTank成员。

,

您的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 { … };
};
,

这是我的方式:

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;
};
本文链接:https://www.f2er.com/3151983.html

大家都在问