美文网首页
C++拷贝控制

C++拷贝控制

作者: m风满楼 | 来源:发表于2018-10-14 21:55 被阅读0次

前言

C++通过在类中定义几个成员函数来控制的对象的拷贝,移动,赋值和销毁,分别如下:

  1. 拷贝构造函数和移动构造函数定义:当用同一类型的另一个对象初始化本对象时做什么(注意区分初始化和赋值)
  2. 拷贝和移动赋值函数定义:将一个对象赋予同类型的的另一个对象的时候做什么
  3. 析构函数定义当此类型对象销毁时做什么

拷贝,赋值,销毁。

1. 拷贝构造

C++拷贝构造函数是一种特殊的构造函数,用于同一类中之前创建的对象来初始化新创建的对象。拷贝构造函数的名称必须和类名称一致,它的第一个参数必须是一个本类型对象的引用(原因是如果不是引用,则函数实参的初始化需要执行拷贝初始化,但拷贝初始化又需要调用拷贝构造,造成死循环),且任何额外的形参都有默认值。
有3种情况会调用拷贝构造函数:

  1. 通过使用一个已有的同类型对象来初始化新创建的对象A a2 = a1
  2. 对象作为参数传递给函数 如下面a2.get(a1)
  3. 从函数返回这个对象时会调用拷贝构造

下面分别使用代码来说明几种调用情况:

#include <iostream>
using namespace std ;
class A{
private:
    int _a ;
public:
    A(int a){
        _a = a ;
        cout<< "this is a's  constructor function"<< endl  ;
    }
    A(const A &a){
        cout << "this is a's copy constructor function" << endl ;
    }
    ~A(){
        cout << "this is a's destructor function" << endl ;
    }
    A getA(A a){
        return a ;
    }
    void   printA(){
        cout<< _a <<endl ;
    }

} ;
A constructor_aA(){
    A a(12) ;
    return a ;
}
int main(){
    A a1(10) ;
    a1.printA() ;
    cout << "====1======" <<endl ;
    //第一种情况,使用已初始化的对象初始化未初始化的对象的时候调用拷贝构造函数
    A a2 = a1 ;  //拷贝构造,区别以拷贝赋值的形式:   a2 = a1
    //第一种情况,使用已初始化的对象初始化未初始化的对象的时候调用拷贝构造函数,括号法
    A a3(a1);  //拷贝构造
    cout << "=====2=====" <<endl ;
    //第2种情况,复制对象把它作为参数传递给函数。
    a2.getA(a1) ;  //实际上发生的是  A a = a1 ; //拷贝构造,实际上还发生了一次      return的返回值会被拷贝构造给一个新的类对象,此处没有接收
    cout << "=====3=====" <<endl ;
    //第3种情况,函数返回一个对象
    A a4 = constructor_aA(); 
    cout << "==========" <<endl ;;
    return 0 ;
}
- 注意区分拷贝构造和拷贝初始化,初始化是行为,需要调用拷贝构造函数。
2. 拷贝赋值

拷贝赋值发生在下面的这种情况:

A a ,b ;
b = a ;
  • 重载运算符:本质是一种函数,函数名称由operator关键字后接表示要定义的运算符的符号组成。因此,赋值运算符就是一个名为operator=的函数,和其他函数类型,运算符函数也有返回值和参数列表。
    Foo& operator=(const Foo&) ; //赋值运算符
  • 如果一个类没有定义拷贝赋值运算符,则编译器会自动合成一个合成拷贝赋值运算符
  • 默认的拷贝赋值运算符会将运算符=右侧的对象的非static成员赋予左侧运算符对象的相应成员,对于数组类型成员,会逐个赋值数组元素。
3.析构函数
  • 析构函数释放对象使用的资源,并销毁对象的非static数据成员
  • 在析构函数中,先执行函数体,然后销毁成员,也就是说,析构函数自身并不销毁成员,成员时在析构函数之后隐含的析构阶段被销毁的。
  • 调用时机:
    • 变量离开作用域
    • 当一个对象被销毁,其成员被销毁
    • 容器被销毁,其元素被销毁
    • 动态分配的对象,当指向它的指针应用delete运算符时销毁
    • 对于临时对象,当创建它的完整表达式被销毁。
      合成的析构函数不会delete一个指针成员
一般情况下,需要析构函数的类都需要拷贝和赋值操作。
需要拷贝操作的类也需要赋值操作,反之亦然

=default 显示要求编译器生成合成的控制函数。只能用于拷贝控制函数
=delete将函数定义为删除的函数,表示虽然声明了该函数,但是不能使用。delete必须出现在函数第一次声明的时候。 可以将delete用于普通函数,表示该函数不能被调用。
-当不可能拷贝,赋值,销毁类的成员时,类的合成拷贝控制成员就被定义为删除的(不能拷贝赋值销毁的成员指1.析构函数不能访问,2.某个拷贝构造函数是删除的或private的3. 类的某个常用拷贝赋值运算符是删除的或private的。如果类的某个成员的析构函数是删除的或不可访问的,或是类有一个引用成员,没有初始化器。)其本质是类的数据成员不能默认拷贝赋值删除或销毁。

  • private拷贝控制
    使用将函数声明为private并且不定义它,也可以阻止对象被拷贝或赋值。
拷贝控制和资源管理

对象拷贝时行为有两种情况,一种是对象的拷贝时类的行为像值拷贝,每个对象有自己独立的状态。一种是像指针,副本和原对象使用相同的底层数据。改变副本也会改变愿对象。

相关文章

  • C++ 拷贝控制(二) — 移动构造函数和移动赋值运算符

    相关文章: C++ 拷贝控制(一) — 析构函数、拷贝构造函数与拷贝赋值函数 C++ 引用类型 — 左值引用、常引...

  • C++拷贝控制

    前言 C++通过在类中定义几个成员函数来控制的对象的拷贝,移动,赋值和销毁,分别如下: 拷贝构造函数和移动构造函数...

  • C++拷贝控制

    拷贝控制操作(copy control) 拷贝构造函数(copy constructor)、拷贝赋值运算符(cop...

  • c++拷贝控制

    拷贝控制 当我们定义一个类的时候,一定要注意类的拷贝控制,这就直接关系到类的内存管理。对于一个类的基本操作有:拷贝...

  • C++ 类的拷贝控制

    拷贝控制 有时候我们需要两个类对象互相关联,当其中一个对象修改后也要关联修改另一个,用这个例子说明拷贝控制的案例。...

  • c/c++/c++11 浅拷贝和深拷贝

    目录 1 c++拷贝 1.1 拷贝构造函数1.2 浅拷贝1.3 深拷贝 2 c语言拷贝 2.1 浅拷贝2.2 深拷...

  • C++ 拷贝控制(一) — 析构函数、拷贝构造函数与拷贝赋值函数

    什么是 C++ 的拷贝控制 ? 我们知道在 C++ 当中,类类型是一种由用户自定义的数据类型。既然是数据类型,我们...

  • C++中容易被忽略的基础知识

    const和define的区别C++中static关键字的总结C++中的构造函数及深拷贝浅拷贝c++基础之引用和指...

  • C++拷贝构造函数和友元

    拷贝构造函数和友元 C++控制类对象私有部分的访问,但有时候需要在类的外部访问类的私有成员,这种情况下C++提供了...

  • [C++之旅] 15 深拷贝与浅拷贝

    [C++之旅] 15 深拷贝与浅拷贝 拷贝构造函数分为深拷贝和浅拷贝两种方式 浅拷贝只是将被拷贝的对象的成员直接赋...

网友评论

      本文标题:C++拷贝控制

      本文链接:https://www.haomeiwen.com/subject/hnitzftx.html