考虑我正在创建两个类的对象:
BaseClass B;
DerievedClass D;
然后我在做:
B=D;
D=B;
哪个是合法的,为什么。这是一个C ++相关工作的面试官提出的问题。我知道大多数是B = D;将是有效的(对象切片);但它是这样D = B;只有在B有默认构造函数时才有效?是的,那为什么呢?
答案 0 :(得分:6)
B=D;
D=B;
第一行将始终编译。第二行可能编译也可能不编译,因为它完全取决于你如何编写每个类。答案的其余部分将阐明它。请继续阅读。
是这样D = B;只有在B有默认构造函数时才有效吗?
没有
D=B
仅在D已定义operator=
作为参数时才有效。
B
或者,如果您在Derived & operator=(const Base &base); //member of Derived
Base B;
Derived D;
D = B; //allowed - assignment
的初始化中执行此操作,则仅当D
的构造函数将D
作为参数时才有效。
B
或Derived(const Base &base); //a constructor of Derived
Base B;
Derived D = B; //allowed - initialization
已将用户定义的转化定义为B
。
D
答案 1 :(得分:0)
BaseClass::BaseClass( const BaseClass& other ) { ... } // Implicit
此复制构造函数将由DerivedClass继承,但在执行D = B时,编译器将查找DerivedClass(const BaseClass&)方法,该方法不存在。
DerivedClass::DerivedClass( const DerivedClass& other ); // Implicit
DerivedClass::BaseClass( const BaseClass& other ); // Inherited
DerivedClass::DerivedClass( const BaseClass &other ); // Not defined!
答案 2 :(得分:0)
如果没有看到类的实现,你就不能假设这两个中的任何一个都会编译!
第一种情况:B=D
除非B的=运算符已经过载,否则它将被编译,在这种情况下甚至B=B
可能是非法的。您可以说,如果B=B
合法,那么B=D
也是合法的,因为D
是BaseClass
类的有效实例。
第二种情况:D=B
纳瓦兹已经对此进行了适当的讨论。但简而言之,您需要明确允许它。你可以:
定义相等的运算符:
DerivedClass::operator=(const BaseClass& copy)
定义显式转化运算符:
BaseClass::operator DerivedClass() const
在DerivedClass
中添加一个接受BaseClass
:
DerivedClass::DerivedClass(const BaseClass&)
请注意,第二种和第三种溶液不应共存,第三种溶液通常应优先使用。只有在您无法修改类或者您想要转换为非类的类型的情况下,转换运算符才会存在。