Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 子类化、赋值运算符和复制构造函数_C++_Constructor_Copy_Operator Keyword_Subclassing - Fatal编程技术网

C++ 子类化、赋值运算符和复制构造函数

C++ 子类化、赋值运算符和复制构造函数,c++,constructor,copy,operator-keyword,subclassing,C++,Constructor,Copy,Operator Keyword,Subclassing,我有一大堆与此相关的问题,我找不到确切的答案。 类A是主类,B是子类 如果定义了A::operator=(const A&other),那么B::operator=的默认实现是否会复制B的成员,然后调用A::operator= 如果定义了复制构造函数,那么B的复制构造函数的默认实现是否会构造B的成员,然后调用复制构造函数 我是否需要在虚拟中定义上述函数以获得此行为?(我假设operator=为是,copy构造函数为否,因为虚拟构造函数毫无意义?) 我是否可以禁止重载A的子类的赋值运算符或复制构造

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

  • 如果定义了A::operator=(const A&other),那么B::operator=的默认实现是否会复制B的成员,然后调用A::operator=

  • 如果定义了复制构造函数,那么B的复制构造函数的默认实现是否会构造B的成员,然后调用复制构造函数

  • 我是否需要在虚拟中定义上述函数以获得此行为?(我假设operator=为是,copy构造函数为否,因为虚拟构造函数毫无意义?)

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

  • 这背后的想法是为我的用户提供一个插件API。我需要API作为C++,因为脚本太慢(我会尝试JIT编译一天),但是它应该非常简单。
  • 如果未删除类
    B
    的默认复制赋值运算符,[class.copy]/28

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

  • 类似地,[class.copy]/15

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

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

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

    为了使派生类
    B
    中的虚拟函数重写基类
    a
    中的虚拟函数,它必须具有相同的参数类型。也就是说,您可以有一个
    虚拟a&operator=(常数&)A
    中的code>,但是类
    B
    中的重写必须看起来像
    virtualb&operator=(常数&)
    ,由于参数类型的原因,不是
    B
    的复制赋值运算符

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

    class A {};
    class B { int i; };
    
    A a;
    B b = a; // using A::operator=(A const&)
    
  • 如果未删除类
    B
    的默认复制赋值运算符,[class.copy]/28

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

  • 类似地,[class.copy]/15

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

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

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

    为了使派生类
    B
    中的虚拟函数重写基类
    a
    中的虚拟函数,它必须具有相同的参数类型。也就是说,您可以有一个
    虚拟a&operator=(常数&)A
    中的code>,但是类
    B
    中的重写必须看起来像
    virtualb&operator=(常数&)
    ,由于参数类型的原因,不是
    B
    的复制赋值运算符

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

    class A {};
    class B { int i; };
    
    A a;
    B b = a; // using A::operator=(A const&)