老是搞混复制构造函数和赋值操作符

oract666 2008-10-13 10:33:28
请教一下,复制构造函数和赋值操作符的区别。

例如:
class_a test1=test2;
那么就会调用复制构造函数去生成test1

class_a test1;
test1=test2;
那么就会采用赋值操作符去给test1 赋值

是这样吗??
...全文
331 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
paddybear 2012-03-02
  • 打赏
  • 举报
回复
10楼正解!
qq364027854 2011-10-21
  • 打赏
  • 举报
回复
赋值操作室没有对象生成,不会调用构造函数的,而复制构造函数是在创建对象赋值的时候调用,是有新对象生成的,会调用构造函数的
lingol 2008-10-13
  • 打赏
  • 举报
回复
不好意思,漏了点东西:

// A& operator = (const A&)
A& operator = (const A& src)
lingol 2008-10-13
  • 打赏
  • 举报
回复
楼主不妨这样想一想,为什么C++要把复制构造函数和赋值函数之分?
其实一般复制构造函数体和赋值函数体一摸一样,只有一个地方不同:
用复制构造函数时,你不能假定目标对象已经获得了所需的资源。
例如:

class A
{
private:
char* ch;
public:
A()
{
ch = new char[10];
}
A(const A& src)
{
ch = new char[10];
memcpy(ch, src.ch, 10);
}
A& operator = (const A&)
{
memcpy(ch, src.ch, 10);
}
};

看看上面的后两个函数的区别。

有人可能说:“那原来调用复制构造函数的地方,编译器自动转换成先调用
默认构造函数,再调用赋值函数不就可以去掉复制构造函数了吗?”
这就涉及效率问题了。
zclever 2008-10-13
  • 打赏
  • 举报
回复
复制(拷贝)构造函数,是用一个已知的对象去初始化另一个正在创建的对象;
赋值操作,是用一个已经存在的对象去更新另一个已经存在的对象。
oract666 2008-10-13
  • 打赏
  • 举报
回复
多谢,编了个测试程序:


#include <iostream>
using namespace std;

class test_a
{
public:
test_a(){ i=0; };
test_a(int p) { i=p; };
test_a(const test_a &p)
{
i=p.show_i();
cout<<"Using copy func!"<<endl;
};
test_a & operator=(const test_a &p)
{
i=p.show_i();
cout<<"Using == func!"<<endl;
return *this;
};
int show_i() const { return i; };
private:
int i;
};

int main()
{
test_a a1(100);
test_a b=a1;
b=a1;
return 0;
}
~
"test77.cpp" 31L, 660C written
[c@testsvr cpp]$
[c@testsvr cpp]$
[c@testsvr cpp]$ CC ./test77.cpp -o ./test77
[c@testsvr cpp]$
[c@testsvr cpp]$
[c@testsvr cpp]$
[c@testsvr cpp]$ ./test77
Using copy func!
Using == func!

baihacker 2008-10-13
  • 打赏
  • 举报
回复
调用构造函数的时候,那个对象还不存在,就像人还没有出生一样.
赋值的时候,已经存在了,但是要变成另一个.
chenzhp 2008-10-13
  • 打赏
  • 举报
回复

楼主说的对

初始化 就是 定义的时候赋值
赋值 可以在变量后续的生存期继续 进行
vcgaoshou 2008-10-13
  • 打赏
  • 举报
回复
你说的对

class_a test1=test2; 中的=属于初始化,因此要调用复制构造函数去生成test1

class_a test1;
test1=test2;
属于赋值,不调用复制构造函数,而是赋值运算

赵Andy 2008-10-13
  • 打赏
  • 举报
回复
这个例子不知行不行?
赵Andy 2008-10-13
  • 打赏
  • 举报
回复
#include<iostream>
using namespace std;
class c
{
public:
c(int i=0):ii(i){}
c(const c &p)
{
cout<<"调用复制构造函数"<<endl;
ii=p.ii;
}
c& operator=(const c&p)
{
cout<<"调用赋值构造函数"<<endl;
ii=p.ii;
return *this;
}
private:
int ii;
};
int main()
{
c cc(8);
c ccc;
ccc=cc;
c c4=cc;
return 0;
}
nuptwzp 2008-10-13
  • 打赏
  • 举报
回复
个人认为2个都是调用的operator +吧,应该都是赋值操作符赋值吧
oract666 2008-10-13
  • 打赏
  • 举报
回复
先说最简单的:

如果我既不显示定义复制构造函数也不显示重载赋值操作符,那么会自动生成这两个函数,是吗?

需要显示定义或者重载的后面再讨论
minorcxx 2008-10-13
  • 打赏
  • 举报
回复
是的
xf_pan 2008-10-13
  • 打赏
  • 举报
回复
具体要看你class_a 是怎么定义的。。
以及重载函数 operator= 是怎么定义的。。
Nosky100 2008-10-13
  • 打赏
  • 举报
回复
类的赋值操作符一般都是重载出来的吧?

大多数重载中应该是在调用拷贝构造函数吧?
否则赋值操作符要调一次构造函数,一次内存拷贝。

我是这样理解的。楼主可以去伪存真。
woaiyu_liang 2008-10-13
  • 打赏
  • 举报
回复
复制构造函数和赋值操作符的区别(以类MyTest为例):
一、函数原型上的区别
复制构造函数的函数原型:MyTest(const MyTest&);//一般用const形参
赋值操作符函数的函数原型:MyTest& operator=(const MyTest&);

二、调用时机上的区别
在以下两种情况下,将调用复制构造函数:
1、当定义一个对象并用同一类型的对象对它初始化时
如:MyTest t1;
MyTest t2(t1);
MyTest t3=t1;

2、当将该类型的对象传递给函数或从函数返回该类型的对象时
如:MyTest& MyTest::Return(MyTest& mt)
{return mt;}

在使用同类型的对象对一个对象赋值时,将调用赋值操作符函数
如:MyTest t1;
MyTest t2;
t2=t1;
晨星 2008-10-13
  • 打赏
  • 举报
回复
从语法上很容易理解啊:
A a = b;//定义并通过拷贝来初始化,因此会调用拷贝构造函数。

A a;//定义并采用默认初始化,因此会调用默认构造函数。
a = b;//这里不是定义,因为前面已经定义过了,因此不会有任何“初始化”,而仅仅是赋值,会调用operator=。

以上假设b也是A类的对象。
xiao9900 2008-10-13
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 lingol 的回复:]
楼主不妨这样想一想,为什么C++要把复制构造函数和赋值函数之分?
其实一般复制构造函数体和赋值函数体一摸一样,只有一个地方不同:
用复制构造函数时,你不能假定目标对象已经获得了所需的资源。
例如:

C/C++ code
class A
{
private:
char* ch;
public:
A()
{
ch = new char[10];
}
A(const A& src)
{
ch = new char[10];
memcpy(ch, src.ch, 10);

[/Quote]

难道仅仅是这点区别?

65,210

社区成员

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

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