2

我有一堆与此相关的问题,我找不到确切的答案。A类是主类,B类是子类

  1. 如果定义了 A::operator=(const A & other) ,则 B::operator= 的默认实现是否复制 B 的成员然后调用 A::operator= ?

  2. 如果定义了 A 复制构造函数,B 的复制构造函数的默认实现是否复制构造 B 的成员,然后调用 A 复制构造函数?

  3. 我是否需要在 A 中定义上述虚拟函数才能获得此行为?(我想对于 operator= 是肯定的,对于复制构造函数来说不是,因为虚拟构造函数是胡说八道?)

  4. 我可以禁止重载 A 的子类的赋值运算符或复制构造函数,以强制使用默认实现吗?

这背后的想法是为我的用户提供插件 API。我需要 API 是 C++,因为脚本太慢了(我有一天会尝试 JIT 编译),但它应该非常简单。

4

1 回答 1

4
  1. 如果没有删除class的默认copy-assignment操作符B,[class.copy]/28

    非联合类的隐式定义的复制/移动赋值运算符X执行其子对象的成员复制/移动赋值。的直接基类X首先分配,按照它们在基说明符列表中的声明顺序[即按照它们在 之后列出的顺序class X : /*here*/ {/*...*/};],然后分配 的直接非静态数据成员X,在它们在类定义中的声明顺序。

  2. 同样,[class.copy]/15

    非联合类 X 的隐式定义的复制/移动构造函数执行其基类和成员的成员复制/移动。

    顺序是:首先是基类(基类子对象),然后是直接的非静态数据成员,类似于 1)。

  3. 对于 1) 和 2) 中描述的行为,没有。虚拟赋值运算符几乎没有用处。构造函数可能根本不是虚拟的(没有意义)。

    为了让派生类B中的虚函数覆盖基类中的虚函数A,它必须具有相同的参数类型。也就是说,您可以virtual A& operator=(A const&);在基类中有 a ,但是由于参数类型,A类中的覆盖B必须看起来像virtual B& operator=(A const&);,这不是的复制赋值运算符。B

  4. 并非没有“黑客”。而且您实际上并没有重载它,而是隐藏了所有基类赋值运算符。否则,这将是合法的:

    class A {};
    class B { int i; };
    
    A a;
    B b = a; // using A::operator=(A const&)
    
于 2013-09-12T10:17:10.877 回答