小弟我的拷贝构造函数哪写错了
我的拷贝构造函数哪写错了?
------解决方案--------------------
拷贝构造函数的参数可以加const修饰,也可以不加const修饰,但是参数必须是引用,如果参数不是引用,将会无限调用拷贝构造函数,况且编译器也不允许使用不是引用类型的参数,如果不使用引用,会发生编译错误。
但不加const修饰,编译器是允许的,编译能够通过,也能正确运行,但在某些地方使用拷贝构造函数,可能会限制拷贝构造函数的参数必须是const类型,比如想在容器中添加类元素,此时就需要调用拷贝构造函数,
比如:当执行这一条语句时v1.push_back(b1);会调用类Base拷贝复制构造函数,然而在容器vector<base>中,push_back()函数的定义是这样的,void push_back(const _Ty& _Val);其中_Ty是模板参数,此时模板形参_Ty被实例化为Base类型,而形参_Val是const类型,
当第一次调用该函数时,该函数又会调用insert(end(), _Val);函数,然而该函数的原型是:iterator insert(const_iterator _Where, const _Ty& _Val);
注意传递过来的参数_Val是const类型,而在insert(end(), _Val);函数中又会调用
_Insert_n(_Where, (size_type)1, _Val);函数,而该函数的原型是:
void _Insert_n(const_iterator _Where,size_type _Count, const _Ty& _Val);
注意形参_Val也是const类型
最后在这个函数中,当执行到Ty _Tmp = _Val;这一条语句时,就会发生错误,原因在于:当执行这一条语句时,会调用类Base的拷贝构造函数,_Val是const类型,而你定义的Base类的拷贝构造函数的形参是非const类型,const类型实参是无法传递给非const类型形参的,所以发生调用错误,而编译器会把Base(Base &b)当成Base(const Base &b)的重载函数,因此编译器会产生无法找到拷贝构造函数的错误。
能够将const类型或非const类型实参传递给Base(const Base &b)的形参,但是不能将const类型的实参传递给Base(Base &b)的形参,而只能将非const类型实参传递给该函数
- C/C++ code
#include<iostream> #include<vector> using namespace std; class Base{ public: Base(){count=0;cout<<"Construct! "<<count<<"time"<<endl;count++;} Base(Base &b); void show(){cout<<"count = "<<count<<endl;} int count; }; Base::Base(Base &b) { count=b.count; cout<<"copyConstruct!"<<endl; } int main(){ Base b1; Base b2; Base b3; vector<Base> v1; v1.push_back(b1); v1.push_back(b2); v1.push_back(b3); vector<Base>::iterator iv; for(iv=v1.begin();iv!=v1.end();iv++){ (*iv).show(); } Base bx= v1.at(0); bx.show(); system("pause"); return 0; }
------解决方案--------------------
拷贝构造函数的参数可以加const修饰,也可以不加const修饰,但是参数必须是引用,如果参数不是引用,将会无限调用拷贝构造函数,况且编译器也不允许使用不是引用类型的参数,如果不使用引用,会发生编译错误。
但不加const修饰,编译器是允许的,编译能够通过,也能正确运行,但在某些地方使用拷贝构造函数,可能会限制拷贝构造函数的参数必须是const类型,比如想在容器中添加类元素,此时就需要调用拷贝构造函数,
比如:当执行这一条语句时v1.push_back(b1);会调用类Base拷贝复制构造函数,然而在容器vector<base>中,push_back()函数的定义是这样的,void push_back(const _Ty& _Val);其中_Ty是模板参数,此时模板形参_Ty被实例化为Base类型,而形参_Val是const类型,
当第一次调用该函数时,该函数又会调用insert(end(), _Val);函数,然而该函数的原型是:iterator insert(const_iterator _Where, const _Ty& _Val);
注意传递过来的参数_Val是const类型,而在insert(end(), _Val);函数中又会调用
_Insert_n(_Where, (size_type)1, _Val);函数,而该函数的原型是:
void _Insert_n(const_iterator _Where,size_type _Count, const _Ty& _Val);
注意形参_Val也是const类型
最后在这个函数中,当执行到Ty _Tmp = _Val;这一条语句时,就会发生错误,原因在于:当执行这一条语句时,会调用类Base的拷贝构造函数,_Val是const类型,而你定义的Base类的拷贝构造函数的形参是非const类型,const类型实参是无法传递给非const类型形参的,所以发生调用错误,而编译器会把Base(Base &b)当成Base(const Base &b)的重载函数,因此编译器会产生无法找到拷贝构造函数的错误。
能够将const类型或非const类型实参传递给Base(const Base &b)的形参,但是不能将const类型的实参传递给Base(Base &b)的形参,而只能将非const类型实参传递给该函数