【C++ Primer】拷贝控制

十三、复制控制

1. 复制构造函数

类中的成员函数都默觉得inline类型。所以即使在类定义体内的函数声明显示定义为inline类型,在进行函数定义时也可以将inline进行省略。

// 复制构造函数应该为常量引用类型,假设同意传值參数会造成无限循环调用从而导致内存溢出。

CopyConstruct(const CopyConstruct& a){value = a.value;}

复制构造函数可用于初始化顺序容器中的元素,如vector<string> svec(5);

这样的方式使用了默认构造函数和复制构造函数。

编译器首先使用string的默认构造函数创建一个暂时值来初始化svec然后使用复制构造函数将暂时值拷贝到svec的每个元素。

数组成员是个例外,假设类具有数组成员。合成复制构造函数将复制数组,它将复制数组的每个元素。注意指针只复制字面值。

复制构造函数在向函数传递该类型的对象和从函数返回该类对象时隐式调用。因此不应该将复制构造函数指定为explicit。

仅仅包括类类型或内置类型(但不包括指针类型的)的类无需显式的定义复制构造函数。

当类有一个成员为指针类型或有成员在构造函数中分配的其它资源,这两种情况下都必须定义复制构造函数。

有些类须要全然禁止复制,如iostream类。假设想禁止复制,类必须显式声明其复制构造函数为private。

此时编译器将拒绝用户代码,不论什么进行复制的尝试。

可是此时在友元和类的成员中还能够进行复制。假设也想禁止它们,能够声明一个private复制构造函数,但不正确其定义。注意是定义。而不是把它定义为一个空的复制构造函数。

声明而不定义成员函数是合法的。可是使用没有定义成员函数的不论什么尝试都将导致链接失败。声明private的复制构造函数后,用户代码不论什么复制类类型对象的尝试都将导致语法错误。而在友元和成员函数的调用将导致链接错误。

假设定义了复制构造函数,编译器就不会合成默认构造函数了。

2. 赋值操作符

假设类未定义自己的赋值操作符,则编译器会合成一个。

赋值操作符的返回类型返回对左/右操作数的引用。且赋值操作符函数必须为类的成员函数,由于赋值必须是类的成员。參数列表中第一个形參为this指针,被省略了。

合成赋值操作符函数与合成复制构造函数操作类似,它也会运行逐个成员赋值。

一般而言假设类须要定义复制构造函数。它也会须要赋值操作符。

3. 析构函数

动态分配的对象仅仅有在该对象的指针被删除时才撤销。

当动态分配对象的引用或指针超出作用域时,不会执行析构函数。

仅仅有显式调用delete才会调用析构函数。但进程结束时会撤销。

假设类须要析构函数,则它也须要赋值操作符和复制构造函数,这被称为三法则。

编译器总会为我们合成一个析构函数,合成的析构函数按对象创建时的逆序撤销每一个非static成员。

对于类类型的成员,合成析构函数会调用该成员的析构函数来撤销对象。

合成析构函数并不删除指针成员所指向的对象。所以一般定义自己的析构函数以释放那些资源。

析构函数与复制构造函数或赋值运算符的一个重要差别是:即使我们编写了自己的析构函数,合成构造函数仍然执行。析构函数仅仅能有一个。

注意:这里使用的是执行。合成构造函数调用成员为类类型的析构函数,用于撤销成员。

4. 管理指针成员

大多数C++类採用下面三种方法之中的一个管理指针成员:

1:指针成员採取常规指针型行为。即不处理。

2:使用智能指针。採取引用计数来控制来管理贡献对象。

     class U_Ptr {
         friend class HasPtr;
         int *ip;
         size_t use;
         U_Ptr(int *p): ip(p), use(1) { }
         ~U_Ptr() { delete ip; }
     };

3:一个指向对象只。每个对象都有其自己的副本。

版权声明:本文博客原创文章,博客,未经同意,不得转载。

时间: 2024-08-01 16:31:23

【C++ Primer】拷贝控制的相关文章

【足迹C++primer】54、继承类的范围,构造函数和拷贝控制

继承类的范围,构造函数和拷贝控制 当用派生类执行函数的时候,首先会在当前的类里面找 如果找不到就一级一级地往上找. Name Lookup Happens at Compile Time class Quote { public: Quote()=default; Quote(const string &book, double sales_price):bookNo(book), price(sales_price) {cout<<"Quote gouzhao functi

【足迹C++primer】45、拷贝控制示例

拷贝控制示例 那么接下来尽情欣赏这个案例吧!!! /** * 功能:拷贝控制示例 * 时间:2014年7月14日10:57:39 * 作者:cutter_point */ #include<iostream> #include<set> #include<vector> #include<string> using namespace std; class Folder; /** Message类 */ class Message { friend void

【足迹C++primer】43、拷贝控制和资源管理

拷贝控制和资源管理 13.2.1行为像值的类 *定义一个拷贝构造函数,完成string的拷贝,而不是拷贝指针 *定义一个析构函数来释放string *定义一个拷贝赋值运算符来释放对象当前的string,并从右侧运算对象拷贝string class HasPtr { public: HasPtr(const string &s=string()):ps(new string(s)), i(0){} //对ps指向的string,每个HasPtr对象都有自己的拷贝 HasPtr(const HasP

《C++primer(第五版)》学习之路-第十三章:拷贝控制

[ 声明:版权所有,转载请标明出处,请勿用于商业用途.  联系信箱:[email protected]] 13.1 拷贝.赋值与销毁 1.当定义一个类时,我们显式地或隐式地指定在此类型的对象拷贝.移动.赋值和销毁时做什么.一个类通过定义五种特殊的成员函数来控制这些操作,包括:拷贝构造函数,拷贝赋值运算符,移动构造函数,移动赋值运算符和析构函数. 2.在一个构造函数中,成员的初始化是在函数体执行之前完成的,且按照它们在类中出现的顺序进行初始化.在一个析构函数中,首先执行函数体,然后销毁成员.成员按

C++ Primer 笔记——拷贝控制

1.如果构造函数的第一个参数是自身类类型的引用,且任何额外参数都有默认值,则此构造函数是拷贝构造函数.拷贝构造函数的第一个参数必须是引用类型(否则会无限循环的调用拷贝构造函数). 2.如果没有为一个类定义拷贝构造函数,编译器会为我们定义一个合成拷贝构造函数.与合成默认构造函数不同,即使我们定义了其他的构造函数,编译器也会为我们合成一个拷贝构造函数. 3.合成的拷贝构造函数会将其参数的成员逐个拷贝到正在创建的对象中(除了static成员).对于类类型的成员,会使用其拷贝构造函数来拷贝,虽然我们不能

C++ Primer学习总结 第13章 拷贝控制

第13章 拷贝控制 1.    什么是拷贝构造函数? P440 如果一个类的构造函数的第一个参数是自己类类型的引用, 且所有其他参数都有默认值, 那么这就是一个拷贝构造函数. 2.    拷贝初始化和直接初始化.  P441 如果初始化的时候使用等号"="来初始化一个对象, 那么就是拷贝初始化. 相反, 如果初始化时, 没有用等号"=", 那么就是直接初始化. 如果是拷贝初始化, 那么用的一定是拷贝构造函数(也有可能用移动构造函数). 如果是直接初始化, 那么就用参

【C++ Primer 第13章】2. 拷贝控制和资源管理

拷贝控制和资源管理 • 类的行为像一个值.意味着它应该有自己的状态,当我们拷贝一个像值得对象时,副本和原对象是完全独立的,改变副本不会对原对象有任何影响. • 行为像指针的类则共享状态.当我们拷贝一个这种类的对象时,副本和原对象使用相同的底层数据,改变副本也会改变原对象. 13.2节练习 1 #include<iostream> 2 #include<string> 3 using namespace std; 4 5 class HasPtr { 6 public: 7 HasP

【C++ Primer 第十三章】4. 拷贝控制示例

拷贝控制示例 1 #include<iostream> 2 #include<string> 3 #include<set> 4 using namespace std; 5 6 class Folder; 7 8 class Message { 9 friend void swap(Message&, Message&); 10 friend class Folder; 11 public: 12 explicit Message(const stri

拷贝控制

当定义一个类时,我们显式地或隐式地指定在此类型的对象拷贝.移动.赋值和销毁时做什么.一个类通过定义五种特殊的成员函数来控制这些操作,包括:拷贝构造函数(copy constructor).拷贝赋值运算符(copy-assignment operator).移动构造函数(move constructor).移动赋值运算符(move-assignment operator)和析构函数(destructor).拷贝和移动构造函数定义了当用同类型的另一个对象初始化本对象时做什么.拷贝和移动赋值运算符定义

C++学习之构造函数和拷贝控制--什么样的情况下才需要虚析构函数

什么样的情况下才需要虚析构函数? 类需要控制自己的对象执行一系列操作时发生什么样的行为,这些操作包括:创建(对象).拷贝.移动.赋值和销毁.在继承体系中,如果一个类(基类或其派生的类)没有定义拷贝控制操作,则编译器将自动的为其合成一个.即为合成的拷贝控制. 在基类的拷贝控制中,由于继承关系导致的最大影响就是:基类通常应该定义一个‘虚析构函数’.用以动态的分配继承体系中的对象. 如:类A,B,C,D有如下继承关系(代码1): 1 2 3 4 class A; class B:public A; c