子类,赋值运算符重载?

时间:2011-09-07 10:21:58

标签: c++ subclass

如果我有下面给出的类:

class TestA
{
    public:
        const TestA &operator=(const int A){return *this;}
};

class TestB : public TestA
{
    public:
        //Inheritance?
};

这个问题假设TestA类和TestB类在变量方面具有完全相同的内容:赋值运算符(或任何其他运算符)是否继承?

以下是否有效?

class TestB : public TestA
{
    public:
        using TestA::operator=;
        //Inheritance?
};

如果有效,会有所作为吗?

4 个答案:

答案 0 :(得分:3)

默认情况下,赋值运算符由派生类隐藏(因为编译器始终为任何T& operator = ()生成class T(如果未指定)。这使得继承的operator =无法使用。

使用using关键字指定时,

;它们变得可用Demo。所以你的代码片段确实有意义。

public: using TestA::operator=;

答案 1 :(得分:3)

问题的示例代码正如我写的那样:

class TestA
{
    public:
        const TestA &operator=(const int A){return *this;}
};

class TestB : public TestA
{
    public:
        //Inheritance?
};

Q1:“赋值运算符(或任何其他运算符)是否继承?”

是的,当然。唯一不在C ++ 98中继承的成员函数是构造函数。但是,自动生成的复制分配运算符默认情况下基类实现隐藏。例如:

#include <iostream>
using namespace std;

class TestA
{
    public:
        TestA const& operator=( int const )
        {
            cout << "TestA = int" << endl;
            return *this;
        }
};

class TestB : public TestA
{
    public:
        // Automatically generated copy assignment operator.
};

int main()
{
    TestB   o;

    cout << "Calling automatically generated copy assignment:" << endl;
    cout << "(should be nothing here ->) ";  o = TestB();
    cout << endl;
    cout << endl;

    cout << "Calling base class assignment operator:" << endl;
    // o = 42;     // won't compile, because it's hidden.
    cout << "(should be output here ->) ";  o.TestA::operator=( 42 );   // OK.
    cout << endl;
}

考虑到目前为止所有的答案都混淆了隐藏和继承,并且只是为了清除这里的术语,N3290(与C ++ 11标准相同)说:

  

N3290§10/ 2:
  “可以以相同的方式在表达式中引用继承的成员   作为派生类的其他成员,除非它们的名称隐藏或含糊不清“

在上面的示例代码中隐藏了TestA::operator=,但请参阅Q3的答案。

Q2:以下是否有效?

此问题涉及在派生类中使用using,例如

class TestB : public TestA
{
    public:
        using TestA::operator=;
        //Inheritance?
};

是的,这是有效的。

它在构造函数的C ++ 98中无效,因为构造函数不是继承的。

<3>问:如果它有效,它会有所作为吗?

是的,它使得基类赋值运算符可以在派生类中直接访问。

例如,您可以删除上面示例中的out-commenting,

// o = 42;     // won't compile, because it's hidden.

它仍然会编译,

o = 42;        // compiles fine with "using".

干杯&amp;第h。,

答案 2 :(得分:2)

我从C ++ 11标准中找到了一些相关的答案:

12.8复制和移动类对象

因为如果未由用户声明,则为类隐式声明复制/移动赋值运算符,则基类复制/移动赋值运算符始终由派生类的相应赋值运算符隐藏(13.5.3)。使用声明(7.3.3)从基类引入一个赋值运算符,其参数类型可以是派生类的复制/移动赋值运算符的参数类型,不被视为此类运算符的显式声明,并且不抑制派生类运算符的隐式声明; using-declaration引入的运算符由派生类中隐式声明的运算符隐藏。

答案 3 :(得分:0)

赋值运算符不是由派生继承的。如果您在派生的基础上使用重载的赋值运算符,则可能会遇到切片:sizeof(base) != sizeof(derived)