【问题标题】:Creating a new pointer to a pure virtual class创建指向纯虚类的新指针
【发布时间】:2014-01-04 19:39:23
【问题描述】:

我有一个如下设计的类:

class Meal {
public:
    virtual void cook() = 0; // pure virtual
}

class Omelette : Meal {
public:
    void cook() {/*do something*/}; // non-virtual
}

class Waffle : Meal {
public:
    void cook() {/*do something*/}; // non-virtual
}

std::vector< std::unique_ptr<Meal> > menu;

void addMeal(const Meal& meal) {
    menu.emplace_back(new Meal(meal)); // cannot allocate an object of abstract type
}

我无法找到将Meal 派生对象添加到menu 的方法,因为我无法创建抽象对象。有没有办法执行上述代码? 我希望Meal 保持抽象。我可以传入一个指向现有 Meal 派生对象的指针,但我的 unique_ptr 几乎不是唯一的。

【问题讨论】:

  • 传入unique_ptr&lt;Meal&gt;; emplace_back 会将其移动到向量中。这是您记录所有权转让的方式。或者,使用 shared_ptr 共享所有权 - 以最适合您设计的其余部分为准。
  • 添加一个名为clone 的虚函数并让每个派生类实现它。在 addMeal 函数中使用该函数。
  • 如@IgorTandetnik 所说,将非过期指针的创建委托给知道它们操作的对象应该工作的代码
  • 这就是factory pattern 派上用场的地方

标签: c++ abstract-base-class


【解决方案1】:

这个问题的解决方法是virtual copy constructor;这在 C++ 中是不允许的(这是不允许的,因为构造函数是与类本身相关的东西,它不能委托给类的子类)。这就是为什么clone 最适合这个问题。

这是similar answer,使用最流行的语法。

所以,你的代码应该是

class Meal {
public:
    virtual void cook() = 0; // pure virtual
    virtual Meal* clone() const = 0; // pure virtual clone.
};

class Omelette : public Meal {
public:
    void cook() {
    /*do something*/ 
    }; // non-virtual
    virtual Omelette* clone() const
    {
        return new Omelette(*this);
    }
};

class Waffle : public Meal {
public:
    void cook() {
        /*do something*/
    }; // non-virtual
    virtual Waffle* clone() const
    {
        return new Waffle(*this);
    }
};

std::vector< std::unique_ptr<Meal> > menu;

void addMeal(const Meal& meal) {
    menu.emplace_back( meal.clone() ); // cannot allocate an object of abstract type
}

【讨论】:

    【解决方案2】:

    您可以实现 getNew 虚拟方法,该方法返回(派生)对象的新副本并使用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-13
      • 1970-01-01
      • 1970-01-01
      • 2015-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多