编译器对普通的构造和拷贝构造处理果然不一样
编译器对普通的构造和拷贝构造处理果然不一样
例:
class A
{
public:
A(A const& another)
{
}
};
class B:public A
{
public:
B()
{
}
B( B const & another)/*:A(another)*/
{
}
};
无法编译
原因: 派生类构造函数需要为基类构造函数提供参数, 当编译器发现基类A只有一个构造函数的版本(参数为: A const& );
所以无法为基类提供参数,导致无法编译。
这是我对B()无法编译的解释。
接着解释下面的例子:
class A
{
public:
/*A(A const& another)
{
}*/
A()
{
}
};
class B:public A
{
public:
B()
{
}
B( B const & another)/*:A(another)*/
{
}
};
编译ok! 此时A这个基类没有版本: A(A const& another),依然可以编译过去,
总结:c++编译器对认为 如果没有拷贝构造函数,那么就默认提供一个,但是如果有了非缺省构造函数(包括拷贝构造),那么 对于派生类无参数的拷贝构造函数来说,是无法编译的。
基类必须提供一个。
[解决办法]
第二个例子虽然能编译,但是行为是错误的,因为 B 的复制构造函数应该调用 A 的复制构造函数,这样的话,你就能看到编译错误了。现在你不调用,B 的复制构造函数执行 A 的默认构造,最后的效果就是 B 中 A 子对象是默认构造的,多余的 B 的成分却是复制构造的,只能导致更难查的 bug.
总结:老老实实的默认调默认,复制调复制吧,别玩儿这杂交的。
[解决办法]
#include <iostream>
using namespace std;
class A
{
public:
A() {cout << "默认构造\n";}
A(const A & a) {cout << "拷贝构造\n";}
};
class B: public A
{
};
int main()
{
B b1;
B b2(b1);
return 0;
}