/*
复制控制:复制构造函数、赋值操作符和析构函数。
复制构造函数:是一种特殊构造函数,具有单个形参,该形参(常用const修饰)是对该类类型的引用。当定义一个对象并用一个同类型的对象对它进行初始化时,将显示使用复制构造函数。当将该类型的对象传递给函数或从函数返回该类型的对象时,将隐式使用复制构造函数
析构函数:是构造函数的互补:当对象超出作用域或动态分配的对象被删除时,将自动应用析构函数。析构函数可用于释放对象时构造或在对象的生命期中所获取的资源。不管类是否定义了自己的析构函数,编译器都自动指向类中非static数据成员的析构函数。
(需要类定义自己的复制控制成员的:类具有指针成员)
复制构造函数可用于:
1.根据另一个同类型的对象显式或隐式初始化一个对象。
2.复制一个对象,将它作为实参传给一个函数。
3.从函数返回时复制一个对象。
4.初始化顺序容器中的元素。
5.根据元素初始化式列表初始化数组元素。
定义形式:
直接初始化(使用括号()初始化)和复制初始化(使用=号初始化)
合成的复制构造函数:合成复制构造函数的行为是,执行逐个成员初始化,将新对象初始化为原对象的副本。
(逐个成员是值编译器将现有对象的每个非static成员,依次复制到正创建的对象)
合成复制构造函数直接复制内置类型成员的值,类类型成员使用该类的复制构造函数进行复制。如果一个类具有数组成员,则合成复制构造函数将复制数组,复制数组的每一个元素。
定义自己的复制构造函数:
复制构造函数就是接受单个类类型引用形参(通常用const修饰)的复制构造函数。例如:
class Foo{
public :
Foo();
//复制构造函数
Foo(const Foo&);
};
因为用于向函数传递对象和从函数返回对象,该构造函数一般不应设置为explicit(抑制隐式转换)
禁止复制:为了防止复制,类必须显示声明其复制构造函数为private。
如果想要连友元和成员中的复制也禁止,就可以声明一个private复制构造函数,但不对其进行定义:
通过声明但不定义private复制构造函数,可以禁止任何复制类类型对象的尝试:用户代码中的复制尝试将在编译时标记错误,而成员函数和友元中的复制尝试将在链接时导致错误。
(注:最好显示定义复制构造函数和默认构造函数)
合成赋值操作符:
合成赋值操作符与合成复制构造函数的操作类似:也是逐个成员赋值,有操作对象的每个成员赋值给做操作数对象的对应成员,对于数组,给每个数组元素赋值。
复制和赋值常一起使用。
析构函数:
构造函数可以完成所需的资源回收,作为类构造函数的补充。
撤销类对象时会自动调用析构函。东带分配的对象只有在指向该对象的指针被删除时才撤销。
如果没有删除指向动态对象的指针,则不会运行该对象的析构函数,对象就一直存在,从而导致内存泄漏,而且对象内部使用的任何资源也不会释放。
当对象的引用或指针超出作用域时,不会运行析构函数。只有删除指向动态分配对象的指针或实际对象(而不是对象的引用)时,才会运行析构函数。
析构函数通常用于释放在构造函数或在对象生命周期内获取的资源。
合成析构函数:
编译器总会为我们合成一个析构函数,合成析构函数按对象创建时的逆序撤销每个非static成员。合成析构函数并不删除指针成员所指向的对象。
编写自己的析构函数:
在类名字之前加上一个代字号(~),它没有返回值,没有形参,不能指定任何形参,所以不能重载析构函数。(一个类只能提供一个析构函数)
(注:即使我们编写了自己的析构函数,合成的析构函数仍然运行。)
管理指针:
悬垂指针:指向一个不复存在的对象的指针。
定义只能指针类:
1.引用使用计数,智能指针将一个计数器与类指向的对象相关联。
2.定义值型类:给指针成员提供值语义:复制值型对象时,会得到一个不同的新副本,对副本的修改不会影响到原有对象上。
分配内存或其他资源的了几乎总是需要定义复制控制成员来管理所分配的资源。
//目前还不能真正的理解复制控制符。。。。
*/
class Foo{
public :
Foo();
//复制构造函数
Foo(const Foo&);
};
int main(){
return 0;
}
C++第十七天 复制控制
最新推荐文章于 2023-12-29 18:55:54 发布