不自动继承的函数

时间:2013-06-06 08:59:07

标签: c++ inheritance operator-overloading

在c ++中,我在布鲁斯·埃克尔读到,不自动继承的函数是:

  1. 构造
  2. 析构
  3. Operator =(因为它像构造函数一样)
  4. 但是这段代码说了别的什么

    #include<iostream>             
    using namespace std;`                   
    
    class A {
     public:
       A & operator= (A &a) {
        cout<<" base class assignment operator called ";
        return *this;
       }
    };
    
    class B: public A { };
    
    int main()
    {
      B a, b;
      a.A::operator=(b); //calling base class assignment operator function
                    // using derived class
      a = b; // this also works
      //getchar();
      return 0;
    
    }   
    

    输出:名为

    的基类赋值运算符

    请解释。

3 个答案:

答案 0 :(得分:0)

事实上,说operator =不是遗传是不正确的。问题在于,对于派生类,隐式生成的operator =隐藏,因此(例如),诸如下面代码中的赋值之类的赋值将是非法的:

A a;
B b;
b = a;

由于类B没有任何operator =接受A,但只有隐式生成的副本赋值运算符具有以下签名:

B& operator = (B const&)

情况与基类中具有相同名称的派生类隐藏成员函数中的常规成员函数的情况没有区别。

对于常规成员函数,您可以在类中使用using声明,使基类的operator =可用:

class B: public A
{
public:
    using A::operator =;
//  ^^^^^^^^^^^^^^^^^^^^
};

这将使前一个例子中的赋值编译。

答案 1 :(得分:0)

根据http://www.linuxtopia.org/online_books/programming_books/thinking_in_c++/Chapter14_010.html,当你没有为你的类定义构造函数,析构函数或=运算符时,它会自动创建这三个函数的简单版本。

“代替继承,这些函数由编译器合成,如果你不自己创建它们。(使用构造函数,你不能创建任何构造函数,以便编译器合成默认构造函数和副本 - 构造函数。)合成的构造函数使用成员初始化,合成的运算符=使用成员分配。“

因此,B有一个由编译器自动生成的合成=运算符。

答案 2 :(得分:0)

A的operator =()没有继承。而是从派生类赋值运算符调用基赋值运算符,因为隐式赋值运算符“简单地”分配所有成员和基类。

(有关何时隐式生成默认副本或移动分配以及使用哪种形式的信息,请参阅标准[草案N3242]§12.8。)

标准(草案N3242)说:

§12.8/ 29

  

非联合类X的隐式定义的复制/移动赋值运算符执行其子对象的成员复制/移动分配。 X的直接基类首先按照它们在base-specifier-list中的声明顺序分配,然后按照顺序分配X的直接非静态数据成员。它们在类定义中声明。

我们得到了赋值运算符。

XBdirect base classA。因此,在B的隐式赋值运算符中,它的A类型的子对象将使用A::operator=(...)进行分配。

注意:通过const引用提供赋值运算符参数是有利的(如果使用copy&amp; swap则通过值提供)。