1

所以,我尝试创建两个相互指向的类(有一个指向另一个类的指针作为私有变量)这里是代码:

class Fruit
{
public:
    Fruit(){
    }
private:
    Plant *thisPlant;
}

class Plant
{
public:
    Plant(){
      thisFruit= new Fruit();
    }
private:
    Fruit *thisFruit;
}

我不确定应该在 Fruit 构造函数中放入什么。我想我不能放 new Plant() 因为它会指向一个新的植物,而且它也会产生一个错误。我想要这样的东西:植物有一个指向水果的变量。Fruit 有一个指向 Plant 的变量。因为我会在 Plant 类中使用一些 Fruit 的公共方法,反之亦然。

关于析构函数,我只想澄清一件事。当我销毁 Fruit 变量时,如果我不输入命令“delete thisPlant;” 对象植物没有被破坏吧?谢谢

4

3 回答 3

4

如果你要放入new Fruit构造Plant函数和构造函数,你最终会得到无限递归new PlantFruit创建 aPlant将创建 aFruit将创建 aPlant将创建 a Fruit,依此类推。

Plant ---> Fruit ---> Plant ---> Fruit ---> ...

但这显然不是你想要的关系。APlant有 a Fruit,但Fruit没有不同的Plant。它肯定希望有一个指向Plant它所属的指针。

Plant <--> Fruit

为此,您的Fruit构造函数应该采用一个类型的参数Plant*,以允许将Plant指向自身的指针传递给Fruit它所拥有的。

class Plant;

class Fruit
{
 public:
  Fruit(Plant* parent){
    parent = parent;
  }
 private:
  Plant* parent;
};

class Plant
{
 public:
  Plant(){
    fruit= new Fruit(this);
  }
 private:
  Fruit* fruit;
};

请注意,Plant构造函数传递this给它的Fruit. Plant现在和之间存在双向关系FruitPlant关于它的知道和关于它FruitFruit知道Plant

现在,请记住,每个人都new必须有一个delete. 这意味着在析构函数中Plant,你应该这样做delete fruit;。当你销毁 aPlant时,它的析构函数会销毁它的Fruit. 你不能这样Fruit做,delete parent;因为它的父级已经被销毁了。ThePlant负责销毁它的Fruit,而不是相反。

于 2013-02-18T19:27:22.797 回答
0

通过“自然”语义层次规则Fruit应该将Plant*指针作为构造函数参数,并且永远不应该使用它的析构函数来触及它。

此外,看起来从 class 继承的具体类Plant应该负责创建Fruit该类的实例(使用 s.th. like new ConcreteFruit(this))。您可以在基类中提供一个 Destructor 实现,该实现Plant将在销毁时销毁此实例。

我认为Fruit并且Plant可以是抽象类,您将在其中派生具体的对,例如

class CherryTree : public Plant 
{ 
    // ... 
}

class Cherry : public Fruit 
{ 
    Cherry(CheryTree* plant) : Fruit(plant) {}
    // ... 
}

或者你需要一些机制使用类属性(例如std::string plantName<=> std::string fruitName)构建对。

于 2013-02-18T19:27:46.697 回答
0

为了摆脱母鸡问题,您可以使用模板:

template <class PlantType>
class Fruit_impl
{
public:
    Fruit_impl(PlantType * parent = 0){
        if(parent == 0)
            parent = new PlantType(this);
        thisPlant = parent;
    }
private:
    PlantType *thisPlant;
};

class Plant
{
public:
    typedef Fruit_impl<Plant> fruit_type;
    Plant(fruit_type * parent = 0){
        if(parent == 0)
            parent = new Fruit<Plant>(this);
        thisFruit = parent;
    }
private:
    fruit_type * thisFruit;
};

typedef Fruit_impl<Plant> Fruit;

请注意,您需要提供某种控制机制以避免递归(请参阅sftrabbit 的答案)。

但是,请注意,在上面给出的实现中存在循环依赖,因此很难删除对象。

于 2013-02-18T19:33:39.157 回答