临时对象问题
以下是两段代码:
代码1:
- C/C++ code
#include <iostream>using namespace std;class Point {private: int x; int y;public: Point(int, int); Point(const Point &); ~Point(); Point operator =(Point);};Point::Point(int i, int j){ x = i; y = j; cout<<"调用一般构造函数"<<endl;} Point::Point(const Point & p){ x = p.x; y = p.y; cout<<"调用拷贝构造函数"<<endl;}Point::~Point() { cout<<"调用析构函数"<<endl; }Point Point::operator =(Point p){ x = p.x; y = p.y; cout<<"重载赋值运算符函数"<<endl; return (*this);}int main( ){ Point pa(20, 35), pb(10, 10); cout<<endl; pa = pb; cout<<endl; return 0;} 这是输出结果:
调用一般构造函数
调用一般构造函数
调用拷贝构造函数 //调用 = 重载运算符之前,会先调用拷贝构造函数,将pb赋值给形参Point P
重载赋值运算符函数
调用拷贝构造函数
调用析构函数
调用析构函数
调用析构函数
调用析构函数
代码2:
- C/C++ code
#include <iostream>using namespace std;class Point {private: int x; int y;public: Point(int, int); Point(const Point &); ~Point(); Point operator =(Point);};Point::Point(int i, int j){ x = i; y = j; cout<<"调用一般构造函数"<<endl;} Point::Point(const Point & p){ x = p.x; y = p.y; cout<<"调用拷贝构造函数"<<endl;}Point::~Point() { cout<<"调用析构函数"<<endl; }Point Point::operator =(Point p){ x = p.x; y = p.y; cout<<"重载赋值运算符函数"<<endl; return (*this);}Point func(Point p){ cout<<"已经进入到func( )的函数体内"<<endl; Point temp(5, 5); return temp;}int main( ){ Point pa(20, 35), pb(1, 2); cout<<endl; pa = func(pb); cout<<endl; return 0;} 这是输出结果:
调用一般构造函数
调用一般构造函数
调用拷贝构造函数
已经进入到func( )的函数体内
调用一般构造函数
调用拷贝构造函数
调用析构函数
调用析构函数
重载赋值运算符函数
/*
函数func()返回一个临时对象,将这个临时对象赋值给pa时,会调用 = 运算符重载函数,在调用 = 运算符重载函数之前,应该会去调用拷贝构造函数,将这个临时对象赋值给形参Point p,可是却并没有调用拷贝构造函数
*/调用拷贝构造函数
调用析构函数
调用析构函数
调用析构函数
调用析构函数
所以我想问一下,为什么会出现这种差异??
[解决办法]
据说编译器是会优化一些东西的
[解决办法]
把Point operator =(Point);
改成 Point& operator =(const & Point);
运行一下
[解决办法]
Point Point::operator =(Point p)
{
x = p.x;
y = p.y;
cout<<"重载赋值运算符函数"<<endl;
return (*this);
}
问题就在这个函数中,你出入实参的时候,编译器会创建一个临时变量的副本,会调用
你写的拷贝构造函数,所以会先 打印 调用拷贝构造函数
当函数返回(*this)的时候,也会创建一个临时的对象调用你的拷贝构造函数了
形参要尽量传引用或者指针,传对象的话会增加构造函数,析构函数开销,如果对象比较大的话还会占用内存开销
返回的时候一样,尽量返回引用或者指针
[解决办法]
Point func(Point p)
{
cout<<"已经进入到func( )的函数体内"<<endl;
Point temp(5, 5);
return temp;
}
你返回的是一个局部的对象,出函数的时候已经被析构了,所以临时对象调用的不是你写的拷贝构造函数
而是默认的拷贝构造函数
[解决办法]
编译器优化了
参考ISO/IEC 14882:2003(E)
12.8 Copying class objects
第15条款
[解决办法]
不知道你的什么编译器,我在V6和code::blocks10.05下都试过,全部是条用的赋值操作
[解决办法]
可能调用情况每个编译器会有不同吧。
拷贝构造和operator=,这样写效率高很多。
Point(const Point&);
Point& operator = (const Point&);
[解决办法]
[解决办法]
我靠,你那比复制构造都用得值传递~
好了,这觉对是优化了,编译器对于临时变量的优化是很正常,更何况你这里简直是2次临时
[解决办法]
就算你自己写了析构函数,还是会再调用一遍自己默认的析构函数,另外我觉得楼主对于答非所问的网友有点不友好
[解决办法]
- C/C++ code
int main( ){ func(Point(Point(3,5))); return 0;}
[解决办法]
就是和构造函数不同,编译器总是会为我们合成一个析构函数的,如果你自己写了析构函数,这个自动合成的析构函数就会调用你写的析构函数。:)
[解决办法]
年轻人不要太气盛,大家都是互相切磋,共同进步,为何态度如此盛气凌人,何况是在提问,一点都不谦虚………