关于复制构造函数的问题!!!完全崩溃!

HisinWang 2010-03-19 01:12:49
#include <iostream>
#include <string>
using namespace std;

class A
{
public:
A(int x): m_x(x) { cout << " 运行构造函数 "; }
~A() { cout << " 运行析构函数 "; }
A(const A &rhs): m_x(rhs.m_x) {cout << " 运行复制构造函数 ";}
void output() const { cout << " ok " << m_x; }
private:
int m_x;
};
int main()
{
A obj(5); //ok, 输出 "运行构造函数" 没有问题
A a = 5; // ok 但是输出的还是 "运行构造函数" 这里完全崩溃,跟C++primer上讲的不一样啊
const A &ref = 6; // ok 输出 "运行构造函数"
A &ref = 6; // error 编译器报告出错
system("pause");
return 0;
}


完全没法理解上面的后三条啊,这与我以前的理解完全相悖!
A a = 5; 按照C++Primer上讲的这里应该调用复制构造函数啊, 因为这里是显示复制初始化啊 由于5不为A类型,那么这里应该调用相应构造函数创建一个临时对象,然后再将这个临时对象传递给复制构造函数创建对象a ,之后应该就是释放临时对象

const A &ref = 6;
A &ref = 6;
这两个也没法理解!!崩溃!!!
望高手指点!!!
...全文
280 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
ShineShineRedStar 2010-03-19
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 taodm 的回复:]

兄弟,你还真够强的,就是不知道自己编译试过没有。
引用 11 楼 ypb362148418 的回复:

LS的不要乱说
A a(5);这个是拷贝构造函数
A aa=a;这个是等号的重载
[/Quote]晕,建议你们把这两句跑跑看,或者翻翻C++ Primer,再来发表言论好吧。
HisinWang 2010-03-19
  • 打赏
  • 举报
回复
受用!!!!
既要理解又要摒弃!!!
万事都是矛盾的。呵呵
taodm 2010-03-19
  • 打赏
  • 举报
回复
哦,那你继续等着在C++这门本来就是修修补补鼓捣出来的语言里继续多碰壁吧。
刘未鹏 语:C++标准就是这样,鬼知道哪个角落的一句话能够带出一个brilliant的解决方案来,同时,鬼知道哪个角落的一句话能够抹杀一个原本简洁的解决方案
lovesi3344 2010-03-19
  • 打赏
  • 举报
回复
脑瘫

A a = 6; 错误

A a(6);正确

A a = A(6);就对了
HisinWang 2010-03-19
  • 打赏
  • 举报
回复
学习一门语言最重要就是理解。
需要理解别人创造这门语言时所使用的模型,和思想。
16楼观点不敢苟同。
taodm 2010-03-19
  • 打赏
  • 举报
回复
问题是,楼主你看过C++标准没?如果这种优化是受C++标准明确支持的呢?
关键其实在于“理解”,学C++更多时候就是靠死记硬背,而不是靠理解的。
多记。
HisinWang 2010-03-19
  • 打赏
  • 举报
回复
哦 还是按照C++标准去理解吧!!!不然没法接受。

理解这种优化简直会导致思维混乱!!!!完全与理论相悖!!!
we_sky2008 2010-03-19
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 wangyao1052 的回复:]
编译器优化是不是会把C++语言标准规定的一些东西改掉啊。如下:
#include <iostream>
#include <string>
using namespace std;

class A
{
public:
A(int x): m_x(x) { cout << " 运行构造函数 "; }
~A() { cout << " 运行析构函数 "; }
A(const A ……
[/Quote]
请搜索 NRVO具名返回值优化
HisinWang 2010-03-19
  • 打赏
  • 举报
回复
编译器优化是不是会把C++语言标准规定的一些东西改掉啊。如下:
#include <iostream>
#include <string>
using namespace std;

class A
{
public:
A(int x): m_x(x) { cout << " 运行构造函数 "; }
~A() { cout << " 运行析构函数 "; }
A(const A &rhs): m_x(rhs.m_x) {cout << " 运行复制构造函数 ";}
void output() const { cout << " ok " << m_x; }
private:
int m_x;
};

A fun()
{
A b(123);
return b;
}
int main()
{
A a = fun();
system("pause");
return 0;
}
结果输出为:“运行构造函数”
也就是说 调用函数时创建的局部对象b没有释放,也没有创建临时对象,只是将a绑定到局部变量b上了 ??
也就是说a就是调用函数时创建的局部变量。
taodm 2010-03-19
  • 打赏
  • 举报
回复
兄弟,你还真够强的,就是不知道自己编译试过没有。
[Quote=引用 11 楼 ypb362148418 的回复:]

LS的不要乱说
A a(5);这个是拷贝构造函数
A aa=a;这个是等号的重载
[/Quote]
ypb362148418 2010-03-19
  • 打赏
  • 举报
回复
LS的不要乱说
A a(5);这个是拷贝构造函数
A aa=a;这个是等号的重载
至善者善之敌 2010-03-19
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 wangyao1052 的回复:]
谢谢!!!
但临时对象什么时候释放呢?
const A &ref = 6;
这个先创建了临时对象,所以是调用构造函数,然后引用了临时对象。
那么这个临时对象什么时候释放呢?
[/Quote]

临时对象也会调用析构函数
ShineShineRedStar 2010-03-19
  • 打赏
  • 举报
回复
A a(5);
A aa = a;
这个时候就能调用复制构造了。
we_sky2008 2010-03-19
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 wangyao1052 的回复:]
谢谢!!!
但临时对象什么时候释放呢?
const A &ref = 6;
这个先创建了临时对象,所以是调用构造函数,然后引用了临时对象。
那么这个临时对象什么时候释放呢?
[/Quote]
ref的生命期结束的时候
HisinWang 2010-03-19
  • 打赏
  • 举报
回复
谢谢!!!
但临时对象什么时候释放呢?
const A &ref = 6;
这个先创建了临时对象,所以是调用构造函数,然后引用了临时对象。
那么这个临时对象什么时候释放呢?
cattycat 2010-03-19
  • 打赏
  • 举报
回复
A a=5;
这个跟A a(5)一样,调用的是构造函数,如果你在你的构造函数前加一个explicit就直接报错了,也就是编译器在这里直接进行了类型转换。

const A &ref = 6;
这个先创建了临时对象,所以是调用构造函数,然后引用了临时对象。

A &ref = 6; // error 编译器报告出错
这个是因为引用临时对象必须是const类型,所以报错了。
至善者善之敌 2010-03-19
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 we_sky2008 的回复:]
C/C++ code

A a = 5; // ok 但是输出的还是 "运行构造函数" 这里完全崩溃,跟C++primer上讲的不一样啊
//编译器做优化 直接将对象构造在a上 省去了临时对象的开销

const A &ref = 6; // ok 输出 "运行构造函数"
//常量引用可以绑定在一个临时对象上

A &ref = 6; // error 编译器报告出……
[/Quote]

很明白了!
we_sky2008 2010-03-19
  • 打赏
  • 举报
回复

A a = 5; // ok 但是输出的还是 "运行构造函数" 这里完全崩溃,跟C++primer上讲的不一样啊
//编译器做优化 直接将对象构造在a上 省去了临时对象的开销

const A &ref = 6; // ok 输出 "运行构造函数"
//常量引用可以绑定在一个临时对象上

A &ref = 6; // error 编译器报告出错
//非常量引用不可以绑定在一个临时对象上

yuzl32 2010-03-19
  • 打赏
  • 举报
回复
1. A a = 5; // ok 但是输出的还是 "运行构造函数" 这里完全崩溃,跟C++primer上讲的不一样啊
---------------
这里按A a(5)处理。因为有A(int)构造函数,所以编译器简单处理了它。

2. const A &ref = 6
-------------
这里先A temp(6)然后ref = &temp; 所以还是输出"运行构造函数"

3. A &ref = 6; // error 编译器报告出错
-----------------------
你可能把6当做地址,直接传递给ref,它们的类型是不一致的。
geegle403 2010-03-19
  • 打赏
  • 举报
回复
const A &ref = 6
把所有构造注释起来,同样不能引用复制构造.
而且因为不能进行隐式转换.对象没初始化,引用找不到对象内存.
加载更多回复(2)

64,642

社区成员

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

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