如果我有下面给出的类:
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?
};
如果有效,会有所作为吗?
答案 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?
};
是的,当然。唯一不在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的答案。
此问题涉及在派生类中使用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)