class A
定义了copy operator,析构函数和operator =。 (Rule of Three)
如果B
继承自A
:
operator=
...我应该为班级B
明确定义吗?答案 0 :(得分:6)
不,这是不必要的。
如果你仔细阅读“三法则”,你会注意到没有关于基类的说法,只能根据类的适当属性和行为做出决定。
(Check this example on ideone)
#include <iostream>
struct A {
A(): a(0) {}
A& operator=(A const& rhs) { a = rhs.a; return *this; }
int a;
};
struct B: A { B(): b(0) {} int b; };
int main() {
B foo;
foo.a = 1;
foo.b = 2;
B bar;
bar = foo;
std::cout << bar.a << " " << bar.b << "\n";
}
// Output: 1 2
这实际上是封装的真正力量。因为您成功使用 Rule of Three ,在使基类 sane 的行为时,其派生类无需知道复制构造函数是否由编译器默认或手动(和复杂)实现,所有对用户而言都很重要(而派生类是用户),是复制构造函数执行复制。
Rule of Three 提醒我们实现细节以帮助实现正确的语义。与所有实现细节一样,它仅对该类的实现者和维护者有用。
答案 1 :(得分:2)
同样的三个规则也适用于派生类 该规则适用于所有类,您可以将它应用于继承层次结构中的每个类,就像将其应用于单个类一样。
如果您的class B
需要三巨头的两个中的任何一个(复制构造函数和析构函数),那么您需要将复制赋值运算符定义为好。
所以它实际上取决于Derived类的成员&amp;您希望Derived类对象的行为。
例如:
如果派生类成员由任何指针成员组成,并且您需要深层副本,那么根据Rule of 3,您的派生类需要重载并为三巨头提供自己的实现。
答案 2 :(得分:1)
将自动调用析构函数
为了一致性
,最好在派生类B中定义析构函数我需要链接构造函数
当然。如果基本构造函数是默认的,那么它的一致性仍然更好。
operator = ...我应该为B类明确定义吗?
是的,就像这样:
struct A
{
A& operator=( const A & r )
{
// assign all A's member variables
return *this;
}
};
struct B : public A
{
B& operator=( const B & r )
{
A::operator=( r );
// assign all B's member variables
return *this;
}
};
答案 3 :(得分:1)
Als说的是正确的,但我不确定他是否回答了你的问题。如果你想在B中做任何具体的事情,除了你在A三巨头中已经做过的事情之外,那么你也没有理由定义B的三巨头。
如果你确实需要其中一个,那么应该适用三个规则。
答案 4 :(得分:0)
这是一个示例代码和输出:
#include <iostream>
class A{
int a;
public:
A():a(0){}
A(A const & obj){std::cout << "CC called\n"; a = obj.a;}
A & operator =(A & a){std::cout << "operator= called\n"; return a;}
~A(){std::cout << "A::dtor called\n";}
};
class B: public A{
};
int main(){
B b,v;
b=v;
}
输出:
operator= called
A::dtor called
A::dtor called