【问题标题】:how to allocate memory for specify type in polymorphism?如何为多态中的指定类型分配内存?
【发布时间】:2017-10-08 04:18:22
【问题描述】:

我有一个抽象类,其他 3 个类从它继承,它们是具体类。我有一个抽象类类型的指针。我想编写一个函数,它接收我提到的 3 个类之一的对象,然后为此分配内存(使用基类指针),然后将传递的对象的值分配给它。我怎样才能new 在我的函数中为该特殊类型提供内存? (我不知道我收到的对象的类型。我只知道它继承自我的抽象类)

谢谢。

【问题讨论】:

  • 你怎么不知道传递给函数的类型?你在传递一个基类指针吗?如果是这样,听起来您需要的是:stackoverflow.com/questions/12255546/…
  • 也许一些示例代码可能有助于说明您的答案...
  • 如果那个函数已经接收到一个对象,为什么还要分配内存?
  • 您是否考虑过实施克隆模式? stackoverflow.com/questions/5148706/…
  • 这就是clone函数的用途。

标签: c++ class inheritance polymorphism


【解决方案1】:

解决它的通常方法是添加一个clone 成员函数,每个类都覆盖它。然而,这可能有点像样板,所以如果你不害怕模板,你可以自动化这个过程:

#include <iostream>
#include <memory>

struct Abstract {
    virtual ~Abstract() = default;
    virtual std::unique_ptr<Abstract> clone() const = 0;
    virtual void                      speak() const = 0;
};

template<class C>
struct Cloneable : Abstract {
        std::unique_ptr<Abstract> clone() const override {
            return std::make_unique<C>(*(C*)this);
        }
};

struct Concrete : Cloneable<Concrete> {
    void speak() const override {
        std::cout << "Concrete";
    }
};

void foo(Abstract& a) {
    a.clone()->speak();
}

int main() {
    Concrete c;
    foo(c);
    return 0;
}

Live Example

它适用于可复制的类。如果您的课程不可复制,您可以自己覆盖clone,然后做有意义的事情。

【讨论】:

    【解决方案2】:

    有两种选择。

    1. 克隆派生类型的对象。
    2. 创建派生类型的默认构造对象。

    它们都可以使用virtual成员函数来实现。

    您可以查看C++: Deep copying a Base class pointer 了解如何克隆对象。

    您可以按照类似的路径返回默认构造的对象。

    struct base {
       virtual ~base() {}                // Remember to provide a virtual destructor
       virtual base* make_new() const = 0;
    };
    struct derived : base {
       virtual derived* make_new() const {
          return new derived(); // Return a default-constructed object.
       }
    };
    

    添加然后在指针上调用make_new()

    【讨论】:

      【解决方案3】:

      我解决这个问题的方法是在抽象基类中添加一个duplicate() 方法,并在每个派生类中实现它。每个实现都确切地知道它有多大,因此它可以使用new 来分配内存。它还确切地知道它有什么内容,因此它可以将它的值分配给新实例。漂亮,简单,优雅。和面向对象的。

      【讨论】:

      • 你能解释一下吗?重复()的返回类型必须是“基类*”??
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-05
      • 1970-01-01
      • 1970-01-01
      • 2015-02-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多