我有一堆与此相关的问题,我找不到确切的答案。 A类是主类,B是子类
如果定义了A :: operator =(const A& other),B :: operator =的默认实现是否复制B的成员然后调用A :: operator =?
如果定义了复制构造函数,B复制的复制构造函数的默认实现是否构造B的成员,然后调用A复制构造函数?
我是否需要在A中定义上述虚拟函数才能获得此行为? (我认为是对于operator =而不是复制构造函数,因为虚拟构造函数是无意义的吗?)
我是否可以禁止为A的子类重载赋值运算符或复制构造函数,以强制使用默认实现?
这背后的想法是为我的用户提供插件API。我需要API是C ++,因为脚本太慢了(有一天我会尝试JIT编译),但它应该非常简单。
答案 0 :(得分:3)
如果未删除类B
的默认复制赋值运算符,[class.copy] / 28
非联合类
X
的隐式定义的复制/移动赋值运算符执行其子对象的成员复制/移动分配。X
的直接基类首先按照它们在 base-specifier-list 中声明的顺序分配[即按照它们在class X : /*here*/ {/*...*/};
之后列出的顺序,然后按照在类定义中声明它们的顺序分配X
的直接非静态数据成员。
同样,[class.copy] / 15
非联合类X的隐式定义的复制/移动构造函数执行其基础和成员的成员复制/移动。
顺序是:首先是基类(基类子对象),然后是直接非静态数据成员,类似于1)。
对于1)和2)中描述的行为,否。虚拟分配运算符几乎没用。构造函数可能根本不是虚拟的(没有意义)。
为了使派生类B
中的虚函数覆盖基类A
中的虚函数,它必须具有相同的参数类型。也就是说,您可以在基类virtual A& operator=(A const&);
中使用A
,但类B
中的覆盖必须看起来像virtual B& operator=(A const&);
,不是 B
的复制赋值运算符,因为参数类型。
不是没有“黑客”。而你实际上并没有重载它,而是隐藏了所有基类赋值运算符。否则,这将是合法的:
class A {};
class B { int i; };
A a;
B b = a; // using A::operator=(A const&)