簡體   English   中英

如何設計一個始終是另一個 class 成員的 Class

[英]How to design a Class that will always be a member of another class

想象一下,我有一個fishTank 這個 class 將代表一個魚缸,它有一個大小,一些魚可以進入的邊界,一些魚不能進入的障礙物,一些水流過魚缸,讓魚四處走動,等等。

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

現在我需要往魚缸里加魚。 聲明我的魚 class 的適當方式是什么? (魚代表一大群個體魚)

  1. 我的魚總是在魚缸里,我一個人fishTank是沒有意義的。
  2. 魚需要知道fishTank的屬性,魚 class 取決於魚缸:魚在魚缸中的裝載方式取決於魚缸的大小,魚的移動方式取決於陷阱的大小和屬性, ETC。
  3. 同一個魚缸里可以有很多不同種類的魚。

我的第一次嘗試是創建魚 class 並將水箱作為參數傳遞給魚構造函數。 然后將魚的向量作為私有成員添加到水箱中:

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;
}

這真的是實現我需要的正確方法嗎? 我只是不認為這是一個好的設計,我需要魚缸作為魚的 arguments,然后將每條魚自己添加到魚缸中。 這有意義嗎?

這是否是實現抽象魚 class 或在水箱內築巢魚之類的正確位置?

老實說,就像吃里斯一樣,沒有正確或正確的方法可以做到這一點。 我個人? 魚缸會有一個魚的向量,然后如果魚需要游泳 1 個刻度,我會在魚缸上有一個游泳方法。 這將調用每條魚並告訴它們游泳,將魚缸作為參數傳遞給它們的游泳方法。 像這樣:

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);
            }
        }
};

關於這個,go 真的有十幾種方法。 我推薦閱讀這樣一本書: Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (ISBN 10: 0201633612)

魚需要知道fishTank的屬性

那么你可以考慮讓fish成為fishTankfriend

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

現在任何fish實例都可以訪問任何給定fishTank實例的所有private成員。

您的Fish class 可以在FishTank class 中聲明,甚至是受保護的或私有的。 這將使在Fish之外使用變得更加困難/不可能。 但是沒有辦法規定它只能是FishTank的直接成員。

class FishTank {
private:
    class Fish {
        Fish(const Fishtank &parent);
        …
    };
    std::vector<Fish> fishInTank;

當在內部聲明 class 時,它自動成為FishTank的朋友,可以訪問坦克的所有成員,包括私人成員。

正如 Paul Evans 所指出的,您還可以使用friend指定來實現后一種效果。 如果Fish是一個復雜的 class 會很有幫助,這會使FishTank class 聲明變得混亂,最好將其保存在另一個 header 文件中。 如果您的FishTank曾經將Fish暴露在外面,至少需要將魚公開; 對於與Fish打交道的任何一方來說,包含完整FishTank header 也可能是一種負擔。

您還可以使用命名空間來解釋語義分組:

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;
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM