拷贝构造函数与赋值构造函数(operator=)的区别

合集下载

详解C++中构造函数,拷贝构造函数和赋值函数的区别和实现

详解C++中构造函数,拷贝构造函数和赋值函数的区别和实现

详解C++中构造函数,拷贝构造函数和赋值函数的区别和实现C++中⼀般创建对象,拷贝或赋值的⽅式有构造函数,拷贝构造函数,赋值函数这三种⽅法。

下⾯就详细⽐较下三者之间的区别以及它们的具体实现1.构造函数构造函数是⼀种特殊的类成员函数,是当创建⼀个类的对象时,它被调⽤来对类的数据成员进⾏初始化和分配内存。

(构造函数的命名必须和类名完全相同)⾸先说⼀下⼀个C++的空类,编译器会加⼊哪些默认的成员函数默认构造函数和拷贝构造函数析构函数赋值函数(赋值运算符)取值函数**即使程序没定义任何成员,编译器也会插⼊以上的函数!注意:构造函数可以被重载,可以多个,可以带参数;析构函数只有⼀个,不能被重载,不带参数⽽默认构造函数没有参数,它什么也不做。

当没有重载⽆参构造函数时,A a就是通过默认构造函数来创建⼀个对象下⾯代码为构造函数重载的实现<span style="font-size:14px;">class A{int m_i;Public:A(){Cout<<”⽆参构造函数”<<endl;}A(int i):m_i(i) {} //初始化列表}</span>2.拷贝构造函数拷贝构造函数是C++独有的,它是⼀种特殊的构造函数,⽤基于同⼀类的⼀个对象构造和初始化另⼀个对象。

当没有重载拷贝构造函数时,通过默认拷贝构造函数来创建⼀个对象A a;A b(a);A b=a; 都是拷贝构造函数来创建对象b强调:这⾥b对象是不存在的,是⽤a 对象来构造和初始化b的!!先说下什么时候拷贝构造函数会被调⽤:在C++中,3种对象需要复制,此时拷贝构造函数会被调⽤1. 1)⼀个对象以值传递的⽅式传⼊函数体2. 2)⼀个对象以值传递的⽅式从函数返回3. 3)⼀个对象需要通过另⼀个对象进⾏初始化什么时候编译器会⽣成默认的拷贝构造函数:1. 1)如果⽤户没有⾃定义拷贝构造函数,并且在代码中使⽤到了拷贝构造函数,编译器就会⽣成默认的拷贝构造函数。

C++在单继承、多继承、虚继承时,构造函数、复制构造函数、赋值操作符、析构函数的执行顺序和执行内容

C++在单继承、多继承、虚继承时,构造函数、复制构造函数、赋值操作符、析构函数的执行顺序和执行内容

C++在单继承、多继承、虚继承时,构造函数、复制构造函数、赋值操作符、析构函数的执⾏顺序和执⾏内容⼀、本⽂⽬的与说明1. 本⽂⽬的:理清在各种继承时,构造函数、复制构造函数、赋值操作符、析构函数的执⾏顺序和执⾏内容。

2. 说明:虽然复制构造函数属于构造函数的⼀种,有共同的地⽅,但是也具有⼀定的特殊性,所以在总结它的性质时将它单独列出来了。

3. 单继承、多继承、虚继承,既然都属于继承,那么虽然有⼀定的区别,但还是相同点⽐较多。

如果放在⼀块讲,但为了将内容制作成递进的,就分开了,对相同点进⾏重复,(⼤量的复制粘贴哈),但在不同点进⾏了标注。

注意:三块内容是逐步递进的如果你懂虚函数,那么单继承和多继承那块你就可以不看;如果你懂多继承,那单继承你就不要看了,⾄于虚继承就等你懂虚继承再回来看吧;如果你只懂单继承,那你就只看单继承就好。

⼆、基本知识1. 对于⼀个空类,例如:class EmptyClass{};虽然你没有声明任何函数,但是编译器会⾃动为你提供上⾯这四个⽅法。

class EmptyClass {public:EmptyClass(); // 默认构造函数EmptyClass(const EmptyClass &rhs); // 复制构造函数~EmptyClass(); // 析构函数EmptyClass& operator=(const EmptyClass &rhs); // 赋值运算符}对于这四个⽅法的任何⼀个,你的类如果没有声明,那么编译器就会⾃动为你对应的提供⼀个默认的(注意合成默认构造函数是⽤于没有编写构造函数编译器才会合成默认构造函数,其中复制构造函数也是构造函数)。

(在《C++ primer》中,这个编译器⾃动提供的版本叫做“合成的***”,例如合成的复制构造函数)当然如果你显式声明了,编译器就不会再提供相应的⽅法。

2. 合成的默认构造函数执⾏内容:如果有⽗类,就先调⽤⽗类的默认构造函数。

复制构造函数与赋值操作符

复制构造函数与赋值操作符

复制构造函数与赋值操作符copy constructor 和copy assignment operator调用时间不一样,假设A同时拥有两者,b是A的一个实例:A a(b)与A a=b 调用得失copy constructorA a;a=b;调用的是assignment operator关于copy constructor和copy assignment的细微区别分类:C++2011-05-12 09:39 54人阅读评论(0) 收藏举报//写法1:T c = a+b;//写法2:T c;c = a+b;对于写法1,编译器会产生一个临时对象,放置a+b。

然后调用c的copy constructor把临时对象当做c的初始值://编译器附加代码:T _temp; //产生临时对象_temp = a+b; //放置a+b的值T c(_temp); //调用c的copy constructor还有一种可能是直接以拷贝构造的方式,将a+b的值放到c中。

T c(a+b);或者实行NRV优化:_result.T::T();//直接计算_result...C++standard允许编译器厂商有完全的自由度,但是由于市场的竞争,几乎保证任何表达式如果有这种形式:T c = a+b;那实现时根本不需要产生一个临时对象。

但是对于写法2,不能忽略临时对象。

它会导致下面结果:T temp;temp.operator+(a,b);c.operator=(temp);temp.T::~T();注意,此时在写法1中的"直接以拷贝构造方式来去除临时对象"或"以NRV优化来消除临时对象"的方法被作用于临时对象temp上。

导致只能消除T temp = a+b此表达式的临时对象,而真正的临时对象temp无法被消除。

不管哪一种情况,直接传递c到运算符函数是有问题的。

由于运算符函数并不为外加参数调用一个destructor(它期望一块新鲜的内存),所以必须在此调用前先调用destructor。

拷贝构造和赋值构造

拷贝构造和赋值构造

拷贝构造和赋值构造你知道什么叫“拷贝构造”和“赋值构造”吗?别急,我来慢慢给你讲。

这两个词儿听起来挺复杂,但它们就像是我们生活中的两个小细节,理解了其实挺简单的。

你看啊,拷贝构造就像你把自己喜欢的照片给朋友复印一份,赋值构造呢,就是你把手头的东西“借”给别人,然后自己又把东西还给自己的过程。

对了,我说的这些你可千万别误会,咱们可不是在聊复印机和借书馆,而是在聊 C++ 编程里的“类”对象的复制和赋值。

让我们先来说说拷贝构造。

拷贝构造的意思呢,就是用已有的一个对象来初始化一个新的对象。

比如你有一个苹果,嗯,还是个特别好的苹果,你想把它复制成另一个一模一样的苹果。

于是你给它复印了一下,结果出来的那个苹果长得一模一样,颜色一样,味道也一样。

就好像你从一个旧手机上拿到了相同的新手机。

拷贝构造就是这种“复印”的过程。

其实啊,这就像你从你最好的朋友那里借了一件超好看的衣服,然后穿上就发现,哇,跟自己的一模一样,简直成了“复制人”。

你知道,C++ 编程中这个拷贝构造器挺重要的,万一你不小心搞错了,你的代码就可能会出现一些不该发生的错误。

想象一下,原本应该是轻松愉快的代码就像是吃了个翻车的苹果,事儿就大了。

赋值构造又是啥呢?赋值构造呢,简单来说就是用一个已经存在的对象来给另一个对象赋值。

这跟拷贝构造有点儿像,但又不完全一样。

赋值构造就像是你已经有了一个苹果,然后你决定把这个苹果的味道、颜色和一切都赋给另一个苹果。

这时候,两个苹果就变得一模一样了,哪怕它们本来是两个独立的个体。

赋值构造有点儿像是你买了两双鞋,决定把一双送给你的朋友,你的朋友穿上之后就和你一模一样,走到哪儿都能“秀”出你们的默契。

这个过程也看似简单,但千万不要小看它,弄得不好,有时候会让你在不经意间犯个大错,就像你以为自己穿的是全新的鞋子,结果脚底下突然有个小洞,慌得一批。

说到这里,可能你会有个问题,拷贝构造和赋值构造它们不是差不多嘛?别着急,我来告诉你,虽然它们看上去挺像,但可大有不同。

c++赋值构造函数

c++赋值构造函数

c++赋值构造函数C++赋值构造函数(Copy Constructor)在 C++ 中,赋值构造函数(Copy Constructor)使用起来很方便。

当一个对象被初始化或者被赋值为另一个对象时,赋值构造函数会自动地执行。

这种初始化或者赋值一般是按值进行的,即用一个对象的所有成员变量的值来初始化或者赋值给另一个对象的成员变量。

有时候,在自定义的类中,按值赋值并不能满足要求。

这时可以自己定义赋值构造函数,以便能够对类变量进行更多的操作。

赋值构造函数是一种特殊的构造函数,它用来初始化一个对象,其参数是另一个同类型的对象。

当一个对象被赋值时,其生存期结束之前,就会调用赋值构造函数。

如果一个对象没有定义赋值构造函数,C++ 会使用默认的赋值构造函数,即将一个对象的所有参数复制到新的对象中。

而如果一个类定义了自己的赋值构造函数,则以用户自己的定义为准,C++ 不会再提供默认的方法。

通常情况下,赋值构造函数用于在创建一个新对象并将其内容初始化为另一个对象时使用。

在 C++ 中,赋值构造函数必须定义为 public 成员函数。

赋值构造函数的语法如下:ClassName (const ClassName& obj) {//}在上面的代码中,obj 是用来初始化一个新对象的对象。

在拷贝构造函数中,应该将obj 的所有成员变量的值复制到当前对象中。

注意事项:1、赋值构造函数通常按引用方式传递对象,以便避免无限递归调用构造函数而导致崩溃的问题。

2、赋值构造函数必须被声明为 const,否则会出现编译错误。

3、赋值构造函数可以在返回值前加上关键词 explicit,这样会规定编译器只使用显式调用,而不进行隐式调用,以免在意外的情况下以错误的方式进行转换。

下面是一个传递了引用参数的 C++ 赋值构造函数的例子,它是类的成员函数:在上述代码中,我们定义了一个名为 Line 的类,其中包括三个公有成员函数和一个私有成员。

C++中拷贝构造函数与赋值运算符使用

C++中拷贝构造函数与赋值运算符使用
通常情况下的简单对象 ,不使用额外系统资源 ,则无须 提供默认拷贝构造函数或默认赋值运算符. 但是 ,如果对象 使用 了系 统资 源 ,就必 须为类提 供拷贝 构造函 数和赋值 运 算符 ,否则会引起如下错误 :
(1) 资源重用 ,任 何一方的 变化都 会影 响另一 方 ,造成 结果错误 ,资源的归属权不清 .
char name [ 20] ;} ; class base2
{public : base2( char 3 pn =“noname”,int x = 0) :obj (pn) { num = x ; cou〈t〈“constructing2 = ”< <“ ”< < num < < endl ;} pro tect ed :
第 22 卷 第 2 期 2006 年 4 月
赤 峰学 院 学报 Journal of Chifeng College
Vol. 22 No. 2 Apr. 2006
C+ +中拷贝构造函数与赋值运算符使用
刘 燕
(赤峰学院 计算机科学与技术系 ,内蒙古 赤峰 024000)
摘 要 : , 在使用过程中非常容
int num ; basel obj ;} ; void main( ) { base2 obj21(“Randy”,12345) ; base2 obj22 = obj21 ;/ / 调用拷贝构造函数 base2 obj23 ; obj23 = obj21 ;}/ / 调用赋值运算符 2. 1 例 1 中 base1 类和 base2 类均没有 提供拷贝 构造函数 和赋值 运 算 符 ,运 行 程 序 会 得 到 正 确 的 结 果 . 构 造 对 象 obj22 时 ,系统先调用 类成 员的 默认拷 贝构造 函数 ,完 成类 成员的拷贝工作 ,然后 再调 用组 合类 的默 认拷 贝构 造函 数 , 完成其它成员的拷贝 工作 . 对象 obj23 被赋值时 ,两 个类均 调用了默认赋值运算符 . 2.2 若在例 1 中只为 base1 类提 供拷 贝构 造函 数和赋值运 算符如下 : base 1 ( base 1 &s) { strcpy(name ,s. name) ; cout < <“copy constructingl”< < name < < endl ;} base 1 &operator = (base 1 &s) { strcpy( name ,s. name) ; cout < <“operator = ”< < name < < endl ; return 3 this;

C++拷贝构造函数和赋值构造函数

C++拷贝构造函数和赋值构造函数

C++拷贝构造函数和赋值构造函数转⾃:⼀、拷贝构造函数int main(int argc, char * argv[]){CExample A;A.Init40);CExample B=A; //把B初始化为A的副本...}B = A ; 此语句的具体过程:⾸先建⽴对象theObjtwo,并调⽤其构造函数,然后成员被拷贝。

语句"CExample B=A;" ⽤ A 初始化 B。

其完成⽅式是内存拷贝,复制所有成员的值。

完成后,A.pBuffer = B.pBuffer, 即它们将指向同样的地⽅,指针虽然复制了,但所指向的空间并没有复制,⽽是由两个对象共⽤了。

这样不符合要求,对象之间不独⽴了,并为空间的删除带来隐患。

所以需要采⽤必要的⼿段(拷贝构造函数)来避免此类情况。

拷贝构造函数的格式为 : 构造函数名(对象的引⽤) 提供了拷贝构造函数后的CExample类定义为:class CExample{public :CExample(){pBuffer=NULL; nSize=0;} //构造函数~CExample(){delete pBuffer;} // 析构函数CExample(const CExample&); //拷贝构造函数void Init(int n){ pBuffer=new char [n]; nSize=n;}private :char *pBuffer; //类的对象中包含指针,指向动态分配的内存资源int nSize;};//拷贝构造函数的定义CExample::CExample(const CExample& RightSides){nSize=RightSides.nSize; //复制常规成员pBuffer=new char [nSize]; //复制指针指向的内容memcpy(pBuffer,RightSides.pBuffer,nSize*sizeof (char ));}这样,定义新对象,并⽤已有对象初始化新对象时,即执⾏语句“CExample B=A; ” 时,CExample(const CExample& RightSides)将被调⽤,⽽已有对象⽤别名RightSides传给构造函数,以⽤来作复制。

拷贝构造函数和赋值函数

拷贝构造函数和赋值函数

拷贝构造函数和赋值函数拷贝构造函数和赋值函数是C++中两个重要的函数,它们都是用来复制对象的。

拷贝构造函数用于创建一个新对象并将其初始化为另一个对象的副本,而赋值函数则用于将一个对象的值赋给另一个对象。

在本文中,我们将详细讨论这两个函数的作用和使用方法。

一、拷贝构造函数拷贝构造函数是一个特殊的构造函数,它用于创建一个新对象并将其初始化为另一个对象的副本。

当我们使用一个对象来初始化另一个对象时,拷贝构造函数就会被调用。

例如:```class MyClass {public:MyClass(); // 默认构造函数MyClass(const MyClass& other); // 拷贝构造函数// ...};MyClass obj1; // 调用默认构造函数MyClass obj2(obj1); // 调用拷贝构造函数```在上面的代码中,当我们使用obj1来初始化obj2时,拷贝构造函数就会被调用。

拷贝构造函数的参数是一个常量引用,它表示要复制的对象。

在拷贝构造函数中,我们可以使用另一个对象的数据来初始化新对象的数据成员,从而创建一个新的对象。

需要注意的是,如果我们没有定义拷贝构造函数,编译器会自动生成一个默认的拷贝构造函数。

这个默认的拷贝构造函数会将一个对象的数据成员逐个复制到另一个对象中。

但是,如果我们的类中有指针类型的数据成员,那么默认的拷贝构造函数可能会出现问题,因为它只是简单地复制指针的值,而不是复制指针所指向的对象。

这时,我们就需要自己定义拷贝构造函数来保证正确的复制。

二、赋值函数赋值函数是用于将一个对象的值赋给另一个对象的函数。

当我们使用一个对象来赋值给另一个对象时,赋值函数就会被调用。

例如:```class MyClass {public:MyClass& operator=(const MyClass& other); // 赋值函数// ...};MyClass obj1, obj2;obj2 = obj1; // 调用赋值函数```在上面的代码中,当我们将obj1赋值给obj2时,赋值函数就会被调用。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

guoshaolong123 | 装扮 | 设置 | 退出
分享酷六视频,赢手机大奖
提交查询内容 如何转贴? 问题反馈
来自:
对于拷贝构造函数以及赋值构造函数的定义,我就不再啰嗦了,还是给出一个简单的例 子,更直观些吧。
class CStr { public:
CStr(); //默认构造函数 CStr(const char* psz); //一种广义拷贝构造函数,不过也有人不认同我的看法 CStr(const CStr& str); //拷贝构造函数 const CStr& operator=(const CStr& str); //赋值构造函数 size_t GetSize() const; //这里的const是什么意思?它必须吗? operator const char*() const { return m_pdata; } protected: const CStr* _Copy(const CStr& str); private: char* m_pdata; size_t m_size; }; CStr::CStr() { m_pdata = NULL; m_size = 0; } size_t CStr::GetSize() const { return m_size; } const CStr* CStr::_Copy(const CStr& str) { if(this != &str) {
w
页码,1/2(W)
guoshaolong123 文章 相册 HOHO 搭讪 对味 照片PK 转贴 投票 测试 礼物 宠物
汽车工厂 七彩鱼 开心大排档
网页游戏
添加 设置
个人中心 我的主页 转贴
好友
消息(3)
个人中心
热门转贴 最新转贴 好友的转贴 我的转贴 紫荆仙草的转贴 转贴
拷贝构造函数与赋值构造函数(operator=)的区别
if(m_pdata){ delete[] m_pdata;
} m_size = str.GetSize(); m_pdata = new char[m_size + 1]; assert(m_pdata); strcpy(m_pdata, str); } return this; } CStr::CStr(const char* psz) : m_pdata(NULL), m_size(0) { assert(psz); if(m_pdata != psz) { if(m_pdata){
delete[] m_pdata; } m_size = strlen(psz); m_pdata = new char[m_size + 1]; assert(m_pdata); strcpy(m_pdata, psz); } } CStr::CStr(const CStr& str): m_pdata(NULL), m_size(0) { _Copy(str); } const CStr& CStr::operator=(const CStr& str)
langyy1288 第一转贴:
紫荆仙草 时间: 2010-11-06 16:50 评论: 0条 投票: 0次 本贴转贴: 0 累计转贴: 1
紫荆仙草的 相关转贴: 为什么虚函数不应该是内联 (inline)函数? 把十进制数转换成十六进制数 ASP动态网页设计教程01 UML课程01 系统进程管理描述
他们也在玩的应用
德克萨斯扑克 扑克限时充值大 优惠啦!快来抢 购吧~ 明星梦工场 经营明星公司, 培养天王巨星! 快来打造... 七彩鱼 美丽宁静的七彩 海域里,住着一 群超萌超...
/share/detail/20967716
2011/1/6
w
页码,2/2(W)
2011/1/6
来自: /langyy1288/blog/item/c69c71d8cf93432a11df9bf1帮助中心 | 空间客服 | 投诉中心 | 空间协议0967716
{ return *(_Copy(str));
} int main() {
const char* psz = "test"; const char* psz1 = "me"; CStr str(psz); //拷贝构造函数,此处调用的是CStr(const char* psz)。 #1 CStr str2(str); // 拷贝构造函数,此处调用的是 CStr(const CStr& str) #2 CStr str1 = psz1; // 拷贝构造,str1此前并不存在,现在要先构造它。 #3 str = str1; // 真正的赋值构造函数 #4 return 0; } 上面这个小型的例子,是我刚刚为大家编写的,这个例子主要就是为了阐述赋值构造函数与 拷贝构造函数之间的区别,其实,我的看法是,赋值构造函数不应该被称为一个构造函数,充其 量只能算得上一个重载的操作符函数。 在C语言中,我们知道"=="是判等操作符,而"="却是一个赋值操作符,所以只要没有出 现"="操作符,也就不会有赋值操作可言。 我之所以认为赋值构造函数不应该被称为一个构造函数,是因为在调用赋值构造函数的时 候,类对象已经存在,自然谈不上构造类对象,它只是对该已经存在的类对象的成员变量进行修 改(所谓的赋值)操作。而拷贝构造函数是利用一个已经存在的类对象构造出一个新的类对象。 回到上面的例子,相信大多数人都应该能分清#1、#2、#4所调用的函数,而对于#3,我想着 重说明的是:赋值构造的实际用意是修改一个已有的对象,而现在str1还没有被定义,所以此处 还是必须要调用拷贝构造函数先产生一个CStr对象。 最后,请大家记住:定义与赋值同时进行的话,必须要先定义,所以必须得先调用拷贝构造函 数,而对于符合单纯的赋值操作语法的语句(也就是只有两个操作数的表达式)来说,才是真正的调 用赋值构造函数。如果大家有什么问题,可以问我,我会尽力为大家讲解。
相关文档
最新文档