复制抽象基类的子类

发布于 2024-10-15 18:18:54 字数 241 浏览 4 评论 0原文

我有一个抽象基类来强制某些子类重载 <<操作员。

我将一堆指向这些子类实例的指针存储在 std::stack 中...有时我希望复制堆栈的顶部项目(并将其推到顶部)。

问题是,我无法实例化抽象类。显然,因为我想为每个子类执行此操作,所以我不知道类型...

我想知道这是否可能在不添加另一个纯虚拟方法(例如“Base *clone() = 0”)的情况下实现在我的每个子类中实现它?当然必须有一种更清洁的方法。

I have an abstract base-class to enforce some subclasses to overload the << operator.

I am storing a bunch of pointers to instances of these subclasses in an std::stack... At some point I wish to duplicate the top item of the stack (and push it on top).

The problem is, I cannot instantiate an abstract class. And obviously since I want to do this for each of my subclasses, I won't know the type...

I wonder if this is even possible without adding another pure virtual method (say 'Base *clone() = 0') and implement it in each of my subclasses? Surely there must be a cleaner way.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

是你 2024-10-22 18:18:54

我认为在这种情况下您实际上需要一个 Clone 方法。您希望在运行时动态复制子类项,而在运行时更改行为的正常方法是虚拟方法。如果不使用某种虚拟方法,您将无法确定它是哪个孩子。不过,您可能可以使用 CRTP 自动为您生成该克隆:

// Totally uncompiled and untested.
class Base
{
public:
    virtual Base* Clone() const = 0;
};

template <class T>
class Child : public Base
{
public:
    virtual Base* Clone() const { return new T(*static_cast<T*>(this)); }
protected:
    Child(); // Can't instantiate directly
    Child(const Child& right); // Can't instantiate directly
};

class Grandchild : public Child<Grandchild>
{
    // Clone should do the right thing.
};

I think you actually need a Clone method in this case. You want to dynamically copy the subclass item at runtime, and the normal way to change behavior at runtime is virtual methods. Without using some virtual method you would have no way of figuring out which child it is. You could probably use CRTP to automatically generate that Clone for you though:

// Totally uncompiled and untested.
class Base
{
public:
    virtual Base* Clone() const = 0;
};

template <class T>
class Child : public Base
{
public:
    virtual Base* Clone() const { return new T(*static_cast<T*>(this)); }
protected:
    Child(); // Can't instantiate directly
    Child(const Child& right); // Can't instantiate directly
};

class Grandchild : public Child<Grandchild>
{
    // Clone should do the right thing.
};
最美不过初阳 2024-10-22 18:18:54

您的意思是制作类的副本,而不是复制指针。

您需要实现自己的打字。换句话说,有一个返回类类型的虚函数,然后创建适当的类

或启用 RTTI(运行时类型信息)来执行相同的操作。因为 RTTI 会影响每个类,所以创建您自己的 typeof 方法可能会更有效。

然后您可以

  1. 弹出指针
  2. 获取类型
  3. 使用实例化正确的类
    复制构造函数可能在
    switch
  4. 将两者推回堆栈

psuedocode

 base* ptr = stack.pop()
 base *copy
 switch (ptr->typeof()) {
  case class1type : copy = new class1(ptr) break;
  case class2type : copy = new class2(ptr) break;
  ...
}

stack.push (ptr)
stack.push(copy)

DC

Do you mean making a copy of the class, rather than duplicating the pointer.

You will need to either implement your own typing. in other words have a virtual function that returns the class type and then create the appropriate class

Or enable RTTI (Run-Time Type Information) to do the same thing. because RTTI effects every class its possibly more efficient to create your own typeof method.

Then you can

  1. Pop the pointer
  2. Get the type
  3. Instantiate the correct class using
    a copy constructor probably in a
    switch
  4. Push both back onto the stack

psuedocode

 base* ptr = stack.pop()
 base *copy
 switch (ptr->typeof()) {
  case class1type : copy = new class1(ptr) break;
  case class2type : copy = new class2(ptr) break;
  ...
}

stack.push (ptr)
stack.push(copy)

DC

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文