下面的两段代码为什么输出不一样??

过往记忆
博客专家认证
2012-08-05 08:27:46
有下面两段代码,为什么输出不一样?
代码一
#include <iostream>

using namespace std;


class AA{
public:
AA(int _first, int _second = 1) : first(_first), second(_second){
cout << "AA:: first = " << _first << " second = " << _second << endl;
}

~AA(){}

AA(const AA & aa){
first = aa.first;
second = aa.second;
cout << "AAAAAA" << endl;
}

AA & operator=(const AA & aa){
first = aa.first;
second = aa.second;
cout << "operator" << endl;
}
int getFirst() const{
return first;
}

int getSecond() const{
return second;
}

private:
int first;
int second;
};

const AA aaaa(const AA &a, const AA &b){
return AA(a.getFirst() * b.getFirst(), a.getSecond() * b.getSecond());
}

int main(){
AA aa(1, 2);
AA temp = aaaa(2, aa);
return 0;
}


代码二
#include <iostream>
#include <string>

using namespace std;

class A{
public:
A(string _name, char _sex, int _age) : name(_name), sex(_sex), age(_age){
cout << "A::" << endl;
}
~A(){
cout << "~A::" << age << endl;
}

A(const A& a){
cout << "AAAA" << endl;
name = a.name;
sex = a.sex;
age = a.age;
}

A& operator=(const A &a){
cout << "operator" << endl;
}

void print(){
cout << name << endl;
cout << sex << endl;
cout << age << endl;
}

private:
string name;
char sex;
int age;
};

A getA(){
return A("wyp", 'm', 24);;
}

int main(){
A a = getA();
return 0;
}


为什么代码一输出
AA:: first = 1  second = 2
AA:: first = 2 second = 1
AA:: first = 2 second = 2

而代码二输出
A::
AAAA
~A::24
~A::24


为什么代码一不在最后输出AAAAAA?(我是在VC++6.0里面编译运行的)
...全文
515 35 打赏 收藏 转发到动态 举报
写回复
用AI写文章
35 条回复
切换为时间正序
请发表友善的回复…
发表回复
DBFNO 2012-08-07
  • 打赏
  • 举报
回复
为什么代码一不在最后输出AAAAAA?
因为AAAAAA是在复制构造函数中输出的内容,因为没有用到复制构造函数所以就不会输出,

int main()
{
AA aa(1, 2);
AA a = aa; //这样就可以输出AAAAAA
AA temp = aaaa(AA(2), aa);
return 0;
}



AA:: first = 1 second = 2 //调用AA(1,2)构造函数

AA:: first = 2 second = 1 //对于aaaa(2,aa),等价于aaaa(AA(2,1(默认参数) ),aa),aaaa函数返回值为 //AA()的构造函数

AA:: first = 2 second = 2//而AA temp = aaaa(2, aa);等价于AA temp = AA(2,2) 用构造函数为其初始化,因此也没有用到复制构造函数


DBFNO 2012-08-07
  • 打赏
  • 举报
回复
[Quote=引用 31 楼 的回复]
知道没有调用,我问的是为什么不调用。。
[/Quote]

因为不存在对象为对象赋值。

至于

const AA aaaa(const AA &a, const AA &b){
return AA(a.getFirst() * b.getFirst(), a.getSecond() * b.getSecond());
}

的行为,我现在解释不清,希望后面的高手详细解释一下,顶起!
DBFNO 2012-08-07
  • 打赏
  • 举报
回复
[Quote=引用 31 楼 的回复:]
A getA(){
return A("wyp", 'm', 24);;
}

int main(){
A a = getA();
return 0;
}
-----------------------------------------------------------------
A::
AAAA
~A::24
~A::24
这里面输出,调用了拷贝构造函数。按30楼的解释是不对的。返回的AA已经是对象了,不是类名的构造。


[/Quote]

当你返回A("wyp", 'm', 24)时,你已经用构造函数创建了一个对象,因此返回的是一个A的对象,当用一个对象为另一对象赋值时当然用到复制构造函数,因此也就输出了AAAAA。你举得这个例子应该不符合楼主的情况。
过往记忆 2012-08-07
  • 打赏
  • 举报
回复
[Quote=引用 30 楼 的回复:]

为什么代码一不在最后输出AAAAAA?
因为AAAAAA是在复制构造函数中输出的内容,因为没有用到复制构造函数所以就不会输出,
C/C++ code

int main()
{
AA aa(1, 2);
AA a = aa; //这样就可以输出AAAAAA
AA temp = aaaa(AA(2), aa);
return 0;
}

C/……
[/Quote]

知道没有调用,我问的是为什么不调用。。
whyboysa 2012-08-07
  • 打赏
  • 举报
回复
[Quote=引用 30 楼 的回复:]

AA:: first = 2 second = 2//而AA temp = aaaa(2, aa);等价于AA temp = AA(2,2) 用构造函数为其初始化,因此也没有用到复制构造函数

[/Quote]
A getA(){
return A("wyp", 'm', 24);;
}

int main(){
A a = getA();
return 0;
}
-----------------------------------------------------------------
A::
AAAA
~A::24
~A::24
这里面输出,调用了拷贝构造函数。按30楼的解释是不对的。返回的AA已经是对象了,不是类名的构造。




过往记忆 2012-08-07
  • 打赏
  • 举报
回复
[Quote=引用 34 楼 的回复:]

引用 31 楼 的回复
知道没有调用,我问的是为什么不调用。。


因为不存在对象为对象赋值。

至于C/C++ code

const AA aaaa(const AA &a, const AA &b){
return AA(a.getFirst() * b.getFirst(), a.getSecond() * b.getSecond());
}


……
[/Quote]

后来我查询了一些资料,貌似这是编译器对函数临时返回值的一些优化。具体什么情况还是不清楚啊。
ha20102010 2012-08-06
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 的回复:]
搞不懂,代码一中的AA temp = aaaa(2, aa)为什么能调用函数aaaa(),
const AA aaaa(const AA &a, const AA &b){
return AA(a.getFirst() * b.getFirst(), a.getSecond() * b.getSecond());
}
参数不是不一样吗?
[/Quote]

整型可以转换成类的对象 ,即2可以转换一个类AA的对象,相当于AA C(2);
whyboysa 2012-08-06
  • 打赏
  • 举报
回复
看来只有11楼理解楼主的意思了。 9楼的高手能说的详细些么。 具体怎么优化的。
过往记忆 2012-08-06
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 的回复:]

搞不懂,代码一中的AA temp = aaaa(2, aa)为什么能调用函数aaaa(),
const AA aaaa(const AA &a, const AA &b){
return AA(a.getFirst() * b.getFirst(), a.getSecond() * b.getSecond());
}
参数不是不一样吗?
[/Quote]
是不一样,但是你没看到那个AA类的构造函数没有加上explicit,说明是隐式转换。如果AA的构造函数加上explicit即
	explicit AA(int _first, int _second = 1, string _name = "XXXX") : first(_first), second(_second), name(_name){

}

这时候上面的代码就通不过编译。。

多多看点书吧。。
过往记忆 2012-08-06
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 的回复:]

代码二中:首先调用getA函数,在函数中构造A对象,即要调用构造函数输出A::,又getA函数返回是个临时对象,即调用类中拷贝构造函数(返回的不是引用),最后调用2次析构函数;
注意,如果代码这样写如下:
A a;
a= getA(); //现在调用的是赋值函数啦;
[/Quote]

这个我知道。。
翠屏阿姨 2012-08-06
  • 打赏
  • 举报
回复
深度探索C++模型一书中有介绍,编译器是如何实现返回值这个特性的:首先声明一个临时的变量,再把函数体重程序员声明且定义的变量赋值给它。所以,你看,一共执行了哪些函数.首先是你的构造函数,然后是拷贝构造,又因为你是在栈上分配的资源,所以稍后就瞬间的释放了资源。
过往记忆 2012-08-06
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 的回复:]

楼主我又回来了,发现了一个问题,就是当成员变量是string类型时,会调用复制构造函数,char和int类型不会调用复制构造函数,我想可能是编译器的优化问题,而不是c++语言本身的问题。因为理论上都是要调用的复制构造函数的。说的不对请见谅。
[/Quote]

呵呵,貌似是被编译器优化了,在g++里面编译两个代码都不会调用复制构造函数,但是在VC 6.0里面代码二会调用复制构造函数,可能是因为里面有string变量,而代码一里面却没有,刚刚我在代码一里面也加了一个string类型的变量,重新编译运行,现在会调用复制构造函数。
过往记忆 2012-08-06
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

AA temp = aaaa(2, aa);
aaaa中参数中的2应该会强制转化了AA类对象c,相当于AA c(2);所以第二次输出是AA:: first = 2 second = 1;
[/Quote]

我不是问你这个。。。。晕。。我是问你为什么不输出AAAAAA
过往记忆 2012-08-06
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]

高手快来解惑,LZ你知道为什么代码一析构函数调用三次么??
[/Quote]
析构函数调用三次我知道,就是不知道为什么复制构造函数为什么不调用。。。
xiaohu023 2012-08-06
  • 打赏
  • 举报
回复
#include <iostream>

using namespace std;


class AA{
public:
AA()
{
first =0;
second =0;
}
AA(int _first, int _second = 1) : first(_first), second(_second){
cout << "AA:: first = " << _first << " second = " << _second << endl;
}

~AA(){}

AA(const AA & aa){
first = aa.first;
second = aa.second;
cout << "AAAAAA" << endl;
}

AA & operator=(const AA & aa){
first = aa.first;
second = aa.second;
cout << "operator" << endl;
}
int getFirst() const{
return first;
}

int getSecond() const{
return second;
}

private:
int first;
int second;
};


/*the orginate code maybe has been optimized
this way will not
*/
static AA *copy_construct_verify;
const AA aaaa(const AA &a, const AA &b){
copy_construct_verify = new AA(a.getFirst() * b.getFirst(), a.getSecond() * b.getSecond());
return *copy_construct_verify;
}

int main(){
AA aa(1, 2);
AA temp =aaaa(2, aa);
delete copy_construct_verify;
return 0;
}
[Quote=引用 9 楼 的回复:]

因为有一个名词叫“优化”。
具体可以去看herb sutter的《exceptional c++》
[/Quote]
zjzjgxw 2012-08-06
  • 打赏
  • 举报
回复
参考 http://blog.csdn.net/ithzhang/article/details/6673050 返回值优化
酱油党 2012-08-06
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 的回复:]

引用 23 楼 的回复:

看来只有11楼理解楼主的意思了。 9楼的高手能说的详细些么。 具体怎么优化的。


是的,上面的人大都回答的不是我要问的。唉。。。
[/Quote]是因为临时变量的原因所以被优化了
过往记忆 2012-08-06
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 的回复:]

看来只有11楼理解楼主的意思了。 9楼的高手能说的详细些么。 具体怎么优化的。
[/Quote]

是的,上面的人大都回答的不是我要问的。唉。。。
过往记忆 2012-08-06
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 的回复:]

C/C++ code
#include <iostream>

using namespace std;


class AA{
public:
AA(int _first, int _second = 1) : first(_first), second(_second){
cout << "AA:: first = " << _first << " second ……
[/Quote]
看来你也理解错我的意思了,那三个输出我是知道的,我是想问问什么不输出AAAAAA,,,
酱油党 2012-08-06
  • 打赏
  • 举报
回复
#include <iostream>

using namespace std;


class AA{
public:
AA(int _first, int _second = 1) : first(_first), second(_second){
cout << "AA:: first = " << _first << " second = " << _second << endl;
}

~AA(){}

AA(const AA & aa){
first = aa.first;
second = aa.second;
cout << "AAAAAA" << endl;
}

AA & operator=(const AA & aa){
first = aa.first;
second = aa.second;
cout << "operator" << endl;
}
int getFirst() const{
return first;
}

int getSecond() const{
return second;
}

private:
int first;
int second;
};

const AA aaaa(const AA &a, const AA &b){
return AA(a.getFirst() * b.getFirst(), a.getSecond() * b.getSecond());//2,2
}

int main(){
AA aa(1, 2);//1,2
AA temp = aaaa(2, aa);//2,1
return 0;
}
加载更多回复(15)

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧