首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

编译器对普普通通的构造和拷贝构造处理果然不一样

2013-08-01 
编译器对普通的构造和拷贝构造处理果然不一样编译器对普通的构造和拷贝构造处理果然不一样例:class A{publ

编译器对普通的构造和拷贝构造处理果然不一样

编译器对普通的构造和拷贝构造处理果然不一样



例:


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.
总结:老老实实的默认调默认,复制调复制吧,别玩儿这杂交的。
[解决办法]

引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

第二个例子虽然能编译,但是行为是错误的,因为 B 的复制构造函数应该调用 A 的复制构造函数,这样的话,你就能看到编译错误了。现在你不调用,B 的复制构造函数执行 A 的默认构造,最后的效果就是 B 中 A 子对象是默认构造的,多余的 B 的成分却是复制构造的,只能导致更难查的 bug.
总结:老老实实的默认调默认,复制调复制吧,别玩儿这杂交的。




派生类的构造,拷贝构造均为默认调用基类的默认构造,如果基类不存在默认构造,而有没有显示调用 

某个版本的个构造函数是错误的


for a derived class, the compiler synthesized 
(1) default ctor calls base class default ctor, and
(2) copy ctor call base class copy ctor.


try to get your facts right before post next time.




class A
{
public:
A()
{
int val = 2;  //进入2次
}

};

class B:public A
{
public:
B( B const & another)
{
}
B(){}
};




int main()
{
B obj;
B obj2 = obj;//断点调试
return 0;
}


我是vs2008 +win7 



我认为你在B中写的拷贝构造函数违反了原本的语义,如果自己写派生类拷贝构造,应该显式的调用基类的拷贝构造完成基类对象的构造。
你用默认的B的拷贝构造,会自动调用A的拷贝构造。
#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;
}


结果显示:
默认构造
拷贝构造

热点排行