BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #40713同步于 2010/6/24
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

请教c++中拷贝构造函数的问题

salooloo
2010/6/24镜像同步15 回复
//4_2.cpp #include <iostream> using namespace std; class Point //Point 类的声明 { public: //外部接口 Point(int xx=0, int yy=0) {X=xx;Y=yy;} //构造函数 Point(Point &p); //拷贝构造函数 int GetX() {return X;} int GetY() {return Y;} private: //私有数据 int X,Y; }; //成员函数的实现 Point::Point(Point &p) { X=p.X; Y=p.Y; cout<<"拷贝构造函数被调用"<<endl; } //形参为Point类对象的函数 void fun1(Point p) { cout<<p.GetX()<<endl; } //返回值为Point类对象的函数 Point fun2() { Point A(1,2); return A; } //主程序 int main() { Point A(4,5); //第一个对象A Point B(A); //情况一,用A初始化B。第一次调用拷贝构造函数 cout<<B.GetX()<<endl; fun1(B); //情况二,对象B作为fun1的实参。第二次调用拷贝构造函数 B = fun2(); //情况三,函数的返回值是类对象,函数返回时,调用拷贝构造函数 cout<<B.GetX()<<endl; return 0; } 错误出在倒数第3行——B = fun2(); no matching function for call to `Point::Point(Point)' 这个程序在vc6.0编译是通过的 但在eclipse下就出现了上述错误 我在网上搜了下 有人说:这个程序本身就有问题 定义了拷贝构造函数,却不重载赋值操作符 可能碰到机器和编译器不同,问题就暴露了! 没搞明白 定义了拷贝构造函数就必须重载赋值操作符吗???
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
graceman机器人#1 · 2010/6/24
对,它们是一对。。 【 在 salooloo (salooloo) 的大作中提到: 】 : //4_2.cpp : #include <iostream> : using namespace std; : ...................
loveway2008机器人#2 · 2010/6/24
要重载=吧
shunshine机器人#3 · 2010/6/24
B = fun2();用到赋值操作符了,所以要定义
joshualee机器人#4 · 2010/6/24
这是因为g++/gcc对C++语言的要求比较严格的原因 只要你把拷贝构造函数改成Point(const Point &);就可以了 【 在 salooloo 的大作中提到: 】 : //4_2.cpp : #include <iostream> : using namespace std; : ...................
joshualee机器人#5 · 2010/6/24
情况一是显示的调用,肯定是正确的,但你写的G++/GCC不会认为是拷贝构造的,只是编译器找到了一个可以使用的函数而已! 情况二是类型的转化,而不是用的拷贝构造,虽然是自己转化成自己。你查查explicit是什么意思,你就知道第二步编译器做的是什么了。 但是情况三是隐式调用编译器认为是的拷贝构造函数,而你写的显然不是它想要的,它需要的是这个Point(const Point &)类型的copy-constructor 【 在 salooloo 的大作中提到: 】 : //4_2.cpp : #include <iostream> : using namespace std; : ...................
a206206机器人#6 · 2010/6/24
第三个是先调用拷贝构造函数,返回一个point,再赋值运算。定义拷贝构造函数,赋值重载不是必须得,但是最好弄上。确实应该是const,不过请ls解答情况2和explicit有什么关系,加上以后return A到错误了,搞不懂
joshualee机器人#7 · 2010/6/24
第三个函数确是先拷贝后赋值! explicit 表明这个构造函数是显示的,不允许存在类型的转化! 如果把 Point(Point &p)前面用explicit修饰的话,那么void fun1(Point p)的调用也就会出错了!当然是认为在G++/GCC编译器上看,就是C++标准上写的! Point B(A);这个加不加explicit都是不出错的,因为这是个确切的函数调用! 这些都是与函数在调用时怎样选取函数的顺序相关! 【 在 a206206 的大作中提到: 】 : 第三个是先调用拷贝构造函数,返回一个point,再赋值运算。定义拷贝构造函数,赋值重载不是必须得,但是最好弄上。确实应该是const,不过请ls解答情况2和explicit有什么关系,加上以后return A到错误了,搞不懂 : -- : 黑暗凝集灵魂,堕落方能自由 : ...................
a206206机器人#8 · 2010/6/25
【 在 joshualee 的大作中提到: 】 : 第三个函数确是先拷贝后赋值! : explicit 表明这个构造函数是显示的,不允许存在类型的转化! : 如果把 Point(Point &p)前面用explicit修饰的话,那么void fun1(Point p)的调用也就会出错了!当然是认为在G++/GCC编译器上看,就是C++标准上写的! : ................... 类的构造函数只有一个参数时,可以利用classname a=typename v来隐式调用,explicit是禁止这样做的。这才是你说的类型转换。求告知lz的三种情况里哪种用到了。还有我加上explicit,fun1的调用不出错,而且我觉得根本没有错误。到是fun2里return A那句话出错
thynson机器人#9 · 2010/6/25
Point(Point &p)这个构造函数要求的是左值,而你传进去的是右值,所以说类型不匹配。 所谓左值对象,可以理解为能放在赋值号左边的对象。 改成Point(const Point &p)或者Point(Point p)就过了,因为这两种形式匹配参数是右值。