稍微深入点理解C++复制控制
2012-11-02 10:37
204 查看
通过一个实例稍微深入理解C++复制控制过程,参考资料《C++ primer》,介绍点基本知识:
1、在C++中类通过特殊的成员函数:复制构造函数、赋值操作符和析构函数来控制复制、赋值和撤销该类的对象时会发生什么。
2、复制构造函数(copy constructor)是一种特殊的构造函数,具有单个形参,该形参(常用const)是对该类类型的引用;
当定义一个新对象并用一个同类型的对象对它进行初始化时,将显示使用复制构造函数;
当将该类的对象传递给函数或从函数返回该类型的对象时,将隐式使用复制构造函数。
3、复制构造函数可用于:
根据另一个同类型的对象显示或隐式初始化一个对象;
复制一个对象,将它作为实参传给一个函数;
从函数返回时复制一个对象;
初始化顺序容器中的元素;
根据元素初始化式列表初始化数组元素。
4、如果我们在类体中没有定义复制构造函数,编译器就会为我们合成一个复制构造函数。与合成的默认构造函数不同,即使我们定义了其他构造函数,也会合成复制构造函数。
合成复制构造函数的行为:执行逐个成员初始化,将新对象初始化为原对象的副本。
有些类经常有的数据成员是指针,这时我们必须对复制对象时发生的事情加以控制,否则当复制的对象析构或者删除时,对象中的指针不再指向有效对象,则会出现悬垂指针情况,这时我们必须要定义自己的复制构造函数。
5、有些类需要完全禁止复制,例如,iostream类就不允许复制,如果不想复制,则应明确禁止,可以将复制构造函数声明为private,并且不定义。
6、赋值操作符(assignment operator):同复制构造函数一样,如果在类体中没有定义赋值操作符,编译器也会为我们合成一个赋值操作符。它会执行逐个成员复制:右操作数对象的每个成员赋值给左操作数对象的对应成员。
如:
7、析构函数(destructor):是构造函数的互补,当对象超出作用域或动态分配的对象(new、malloc)被删除时,将自动应用析构函数。
下面通过一个实例详细说明复制构造函数、赋值操作符、析构函数的调用机制,代码中已有详细解释,故在此不再赘述~
运行结果:仔细观察运行结果的执行情况,可以深入理解C++中的复制控制机制~
1、在C++中类通过特殊的成员函数:复制构造函数、赋值操作符和析构函数来控制复制、赋值和撤销该类的对象时会发生什么。
2、复制构造函数(copy constructor)是一种特殊的构造函数,具有单个形参,该形参(常用const)是对该类类型的引用;
当定义一个新对象并用一个同类型的对象对它进行初始化时,将显示使用复制构造函数;
当将该类的对象传递给函数或从函数返回该类型的对象时,将隐式使用复制构造函数。
3、复制构造函数可用于:
根据另一个同类型的对象显示或隐式初始化一个对象;
复制一个对象,将它作为实参传给一个函数;
从函数返回时复制一个对象;
初始化顺序容器中的元素;
根据元素初始化式列表初始化数组元素。
4、如果我们在类体中没有定义复制构造函数,编译器就会为我们合成一个复制构造函数。与合成的默认构造函数不同,即使我们定义了其他构造函数,也会合成复制构造函数。
合成复制构造函数的行为:执行逐个成员初始化,将新对象初始化为原对象的副本。
有些类经常有的数据成员是指针,这时我们必须对复制对象时发生的事情加以控制,否则当复制的对象析构或者删除时,对象中的指针不再指向有效对象,则会出现悬垂指针情况,这时我们必须要定义自己的复制构造函数。
5、有些类需要完全禁止复制,例如,iostream类就不允许复制,如果不想复制,则应明确禁止,可以将复制构造函数声明为private,并且不定义。
6、赋值操作符(assignment operator):同复制构造函数一样,如果在类体中没有定义赋值操作符,编译器也会为我们合成一个赋值操作符。它会执行逐个成员复制:右操作数对象的每个成员赋值给左操作数对象的对应成员。
如:
Sales_item& Sales_item::operator=(const Sales_item &rhs) { isbn = rhs.isbn; units_sold = rhs.units_sold; revenue = rhs.revenue; return *this; }
7、析构函数(destructor):是构造函数的互补,当对象超出作用域或动态分配的对象(new、malloc)被删除时,将自动应用析构函数。
下面通过一个实例详细说明复制构造函数、赋值操作符、析构函数的调用机制,代码中已有详细解释,故在此不再赘述~
/************************************************ * * 内容摘要:定义Expm1类,该类给出复制控制成员和其他构造函数 * 用不同方式使用Expm1类型的对象: * 作为非引用形参和引用形参传递,动态分配 * 作为函数返回值,进行赋值操作,作为元素放在vector容器中。 * 研究何时执行哪个构造函数和复制控制成员 * * 日 期:2012.8.27 by Jacky Liu * ************************************************/ #include <vector> #include <iostream> struct Expm1 { //默认构造函数 Expm1() { std::cout<<"Expm1()"<<std::endl; } //复制构造函数 Expm1(const Expm1 &) { std::cout<<"Expm1 (const Expm1&)"<<std::endl; } //复制操作符 Expm1 & operator = (const Expm1 &) { std::cout<<"operator = (const Expm1&)"<<std::endl; return *this; } //析构函数 ~Expm1() { std::cout<<"~Expm1()"<<std::endl; } }; void func1(Expm1 obj) //形参为Expm1对象 {} void func2(Expm1 & obj) //形参为Expm1对象的引用 {} Expm1 func3() { Expm1 obj; return obj; //返回Expm1对象 } int main() { std::cout<<"1-------------------------------------"<<std::endl<<std::endl; Expm1 eobj; //调用默认构造函数创建Expm1对象eobj std::cout<<"2-------------------------------------"<<std::endl<<std::endl; func1(eobj); //调用复制构造函数 //将形参Expm1对象创建为实参Expm1对象的副本 //函数执行完毕后调用析构函数撤销形参Expm1对象 std::cout<<"3-------------------------------------"<<std::endl<<std::endl; func2(eobj); //形参为Expm1对象的引用,无需调用复制构造函数传递实参 std::cout<<"4-------------------------------------"<<std::endl<<std::endl; eobj = func3(); //调用默认构造函数创建局部Expm1对象 //函数返回时调用复制构造函数创建作为返回值副本的Expm1对象 //然后调用析构函数撤销局部Expm1对象 //然后调用赋值操作符 //执行完赋值操作后 //调用析构函数撤销作为返回值副本的Expm1对象 std::cout<<"5-------------------------------------"<<std::endl<<std::endl; Expm1 *p = new Expm1; //调用默认构造函数动态创建Expm1对象 std::vector<Expm1> evec(3); //调用默认构造函数创建一个临时值Expm1对象 //调用复制构造函数,将临时值Expm1对象复制到vector容器evec的每个元素 //调用析构函数撤销临时值Expm1对象 //按以上重复三次 std::cout<<"6-------------------------------------"<<std::endl<<std::endl; delete p; //调用析构函数撤销动态创建的Expm1对象 system("pause"); return 0; //eobj及evec生命期结束,自动调用析构函数撤销 }
运行结果:仔细观察运行结果的执行情况,可以深入理解C++中的复制控制机制~
![](http://pic002.cnblogs.com/images/2012/396755/2012110210350956.jpg)
相关文章推荐
- 稍微深入点理解C++复制控制
- 稍微深入点理解C++复制控制
- 稍微深入点理解C++复制控制【转】
- 【c++primer——】第13章复制控制——01深入理解复制构造函数
- 2013-12-15 【C++-01】:关于复制控制的一点理解
- C++的一大误区-深入理解直接初始化与复制初始化的区别
- 深入理解c++构造函数, 复制构造函数和赋值函数重载(operator=)
- 13章习题 理解复制控制
- C++学习笔记十三-复制控制
- Spring控制反转的深入理解
- 深入理解 C++ 指针(二)---指针的算术运算
- 深入理解c++虚函数
- 深入理解C++浮点数(float、double)类型数据比较、相等判断
- 深入理解C++中的mutable关键字
- C++语法基础--复制控制--复制构造函数 ,赋值操作符 ,析构函数
- 复制控制(学习<C++Primer>)
- laravel服务容器-----深入理解控制反转(IoC)和依赖注入(DI)
- 【转】跟我一起学Spring 3(4)–深入理解IoC(控制反转)和DI(依赖注入)
- 【Solidity】5.表达式和控制结构 - 深入理解Solidity
- 深入理解C++的动态绑定和静态绑定转