提问人:Sideshow Bob 提问时间:3/23/2016 最后编辑:CommunitySideshow Bob 更新时间:3/24/2016 访问量:1579
如何从基类调用派生赋值运算符?
How to call derived assignment operator from base class?
问:
给定一个指向抽象基类的指针,我想复制或赋值它(作为基类)并调用派生的复制构造函数或赋值运算符。我知道复制构造函数不能是虚拟的,所以大概复制构造函数不是执行此操作的选项,但赋值运算符是。不过,它似乎不起作用:以下代码打印A*
assigned a
x!
destroyed b
destroyed b
无法分配 B。
#include <iostream>
using namespace std;
class A
{
public:
virtual void x()=0;
virtual ~A() {}
virtual A& operator=(const A& other) { cout << "assigned a" << endl; return *this;}
};
class B : public A
{
public:
virtual B& operator=(const B& other) { cout << "assigned b" << endl; return *this;}
virtual void x() { cout << "x!" << endl; }
virtual ~B() { cout << "destroyed b" << endl; }
};
int main()
{
A* a = new B();
A* aa = new B();
*aa=*a;
aa->x();
delete a;
delete aa;
return 0;
}
如何做到这一点?
编辑 这个问题在下面得到了正确的回答,但这是错误的问题。我不应该尝试覆盖赋值运算符,因为我不希望 A 的子类相互赋值。有关更简单的答案(希望如此),请参阅 C++ 通过调用基类优雅地克隆派生类
答:
4赞
vsoftco
3/23/2016
#1
问题是 ur 没有覆盖 中的那个。将其更改为B::operator=
A
virtual A& operator=(const A& other) { cout << "assigned b" << endl; return *this;}
它会起作用的。此外,在重写成员函数时尝试使用 override
关键字(需要 C++11)。如果不重写,代码将无法编译。就您而言,它会发现您的错误
错误:“虚拟 B& B::operator=(const B&)”标记为“覆盖”,但不覆盖
PS:您可能正在考虑协变返回类型。为了使其正常工作,函数的签名必须相同,但返回类型除外。例如,这将起作用:
virtual B& operator=(const A& other) { cout << "assigned b" << endl; return *this;}
评论
0赞
Sideshow Bob
3/23/2016
好的,这很好,但是如果它不能保证它是 的实例,如何访问唯一的字段?B::operator=
B
const A& other
B
0赞
Sideshow Bob
3/23/2016
这确实很难,这让我质疑我的设计。最终,我需要从基类指针深层复制一个类,而不知道该类到底是什么。根据封装原则,这不是一个疯狂的要求,对吧?
0赞
Sideshow Bob
3/23/2016
这意味着当只有一个派生类需要默认值以外的任何内容时,为所有派生类提供一个函数(或者在我的情况下可以完成这项工作)。有没有办法说?assign
clone
find the derived class assignment operator (which will be virtual if not default) and use it
评论