首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在纯虚拟基类中不创建显式函数就不能完成复制构造吗?

在纯虚拟基类中不创建显式函数就不能完成复制构造吗?
EN

Stack Overflow用户
提问于 2010-09-28 22:45:29
回答 6查看 230关注 0票数 2

我的目标是做一个类的深层拷贝,但是一个虚拟类造成了麻烦。

代码语言:javascript
复制
#include<iostream>
using namespace std;

class Vir//pure virtual class
{
    public:
    virtual void hi()=0;
};

class Handler:public Vir
{
    public:
    int i;
    Handler() {}
    Handler(int val):i(val) {}
    void hi() {cout<<"Value of i="<<i<<endl;}
    int getI() const {return i;}
    void setI(int j) {i=j;}
};

class ControlPanel
{
    public:
    Vir *v;
    ControlPanel(const ControlPanel& c)//copy constructor
    {
        v=new Handler;
        v->setI(c.getI());
    }
    int getI()const {return v->getI();}

    void initialize() {v=new Handler(10);}
    void hi() {v->hi();}
    ControlPanel() {}
    ~ControlPanel() {delete v;}
};

int main()
{
    ControlPanel cc;
    cc.initialize();
    cc.hi();
    ControlPanel bb(cc);//copying cc into bb
}

编译错误消息:

代码语言:javascript
复制
test.cpp: In copy constructor ‘ControlPanel::ControlPanel(const ControlPanel&)’:
test.cpp:28: error: ‘class Vir’ has no member named ‘setI’
test.cpp: In member function ‘int ControlPanel::getI() const’:
test.cpp:30: error: ‘class Vir’ has no member named ‘getI’

我计划有更多的处理程序类(如Handler1、Handler2等),它们继承自Vir,并将拥有自己的唯一成员(如float a;或double b;等)。因此,将所有Handler类的所有getter & setter函数都保留在Vir类中是没有意义的。我希望将getter和setter方法保留在Handler类中,因为这些成员对于Handler类是唯一的。编译器不允许我这样做。帮助?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2010-10-01 20:48:05

也许我错过了一些东西,但在Vir上使用虚拟clone方法不是更好吗?这意味着您可以避免在您自己的答案中概述的ControlPanel复制构造函数中的讨厌类型转换。这与@Andrew Aylett在his answer中的建议相同,使用duplicate而不是clone

就像这样

代码语言:javascript
复制
class Vir
{
    public:
    virtual Vir* clone() const = 0;
    ...
};

这是在Handler中实现的

代码语言:javascript
复制
Handler* Handler::clone() const
{
    return new Handler( *this );
}

注意协变返回类型的使用,即允许Handler::clone返回Handler*而不仅仅是Vir*,并且仍然是Vir::clone的有效覆盖。

这使得ControlPanel复制构造函数变得简单

代码语言:javascript
复制
ControlPanel( const ControlPanel& c )
    : v( c.v->clone() )
{
}
票数 2
EN

Stack Overflow用户

发布于 2010-09-30 17:38:35

向您的抽象类添加一个duplicate()函数,它(在每个派生类中)创建一个具有正确值的新实例并返回该实例。或者,考虑一个copyFrom(Abs other)函数,该函数进行检查以确保从正确的类型复制,如果是,则将字段复制出来。

通常,如果您的ControlPanel类有一个对Abs对象的引用,它不应该试图通过检查具体的处理程序对象来进行复制,它应该将复制传递给该对象上的一个虚函数。

票数 2
EN

Stack Overflow用户

发布于 2010-09-28 22:54:21

为什么编译器会允许你这样做?这些方法不在该接口上。

你可以使用Factory Pattern来创建你的Vir,以避免将所有的构造函数添加到Vir的接口中,你也应该考虑使用RAII来避免initialize()风格的函数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3813964

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档