zoukankan      html  css  js  c++  java
  • c++拷贝控制

    1、拷贝构造函数

    如果一个构造函数的第一个参数是自身类类型的引用,且任何额外的参数都有默认值,则此构造函数是拷贝构造函数。

    C(const C &);//参数通常是const的引用

    拷贝构造函数在下列情况下发生:

    • 拷贝初始化时使用(=定义变量)。
    • 将一个对象作为实参传递给一个非引用类型的形参。
    • 从一个返回类型为非引用类型的函数返回一个对象。
    • 用花括号列表初始化一个数组中的元素或一个聚合类中的成员。

    拷贝构造函数的参数必须是引用类型,因为如果不是引用的话,调用拷贝构造函数时要拷贝它的实参,拷贝它的实参需要调用拷贝构造函数构造函数,如此无限循环。

    如果我们没有为类定义一个拷贝构造函数,编译器会自动合成一个拷贝构造函数。

    (1)拷贝初始化

    直接初始化是要求编译器使用普通的函数匹配选择与我们提供的实参最匹配的构造函数:

    string s1(10,'c');

    string s2(s1);

    拷贝初始化要求编译器将右侧运算对象拷贝到正在创建的对象中(有时候需要类型转换):
    string s3=s1;

    string s4="abc";

    string s5=string(100,'c');

    拷贝初始化通常使用拷贝构造函数来完成。

    如果在拷贝初始化的过程中需要类型转换,注意使用explicit的构造函数转换时只能用直接初始化:

    vector<int>v1(10);//直接初始化

    vector<int>v2=10;//错误,接受大小参数的构造函数时explicit的,不能类型转换后拷贝初始化

    同理

    void f(vector<int>);

    f(10);//错误

    f(vector<int>(10));正确,//直接构造一个临时的vector

    2、拷贝赋值运算符

    拷贝赋值是通过重载赋值运算符实现的,重载运算符本质上是个函数,由operator关键字后接要重载的运算符组成,重载赋值运算符就是一个名为operator=的函数。

    Foo & operator=(const Foo&){

      //赋值操作

      return *this;

    }

    赋值运算符接受一个与其所在类类型相同的参数,并返回一个指向其左侧运算对象的引用。

    如果我们没有为类定义一个拷贝赋值运算符,编译器会自动合成一个拷贝赋值运算符。

    3、析构函数

     构造函数初始化对象的static数据成员,析构函数释放对象使用的资源,销毁对象的非static数据成员。

    ~C(){}

    • ~接类名构成
    • 没有返回值
    • 不接受参数(因此不重载,唯一)

    析构函数由函数体和析构部分组成,首先执行函数体,然后销毁成员。如果我们没有定义析构函数,编译器会自动合成一个构造函数。

    只要对象被销毁就执行析构函数:

    • 变量离开其作用域
    • 对象被销毁时,其成员也被销毁
    • 容器被销毁时,其元素被销毁
    • 对于动态分配的对象,对它的指针应用delete时被销毁
    • 对于临时对象,创建它的完整表达式结束时被销毁

    隐式销毁一个内置类型的指针不会销毁其指向的对象,如果指针指向的是动态内存,注意用delete销毁对象。

  • 相关阅读:
    Spark Mllib里的向量标签概念、构成(图文详解)
    Spark Mllib里的本地向量集(密集型数据集和稀疏型数据集概念、构成)(图文详解)
    Spark Mllib里的Mllib基本数据类型(图文详解)
    [转]Debugging into .NET Core源代码的两种方式
    [转]在ASP.NET Core使用Middleware模拟Custom Error Page功能
    [转]Asp.net MVC中的ViewData与ViewBag
    [转]细说 ASP.NET Cache 及其高级用法
    [转]分布式中使用Redis实现Session共享(二)
    [转]Asp.net Core 使用Redis存储Session
    [转]JS跨域解决方式 window.name
  • 原文地址:https://www.cnblogs.com/StormWendy/p/8460457.html
Copyright © 2011-2022 走看看