zoukankan      html  css  js  c++  java
  • c++构造函数分类说明

    在面向对象编程中,创建对象时系统会自动调用构造函数来初始化对象,构造函数是一种特殊的类成员函数,它有如下特点:

    1. 构造函数的名子必须和类名相同,不能任意命名;
    2. 构造函数没有返回值;
    3. 构造函数可以被重载,但是每次对象创建时只会调用其中的一个;

    我们可以将构造总结为以下几类,不同入参决定调用不同的构造函数,它们分别是普通构造函数 、默认构造函数 、拷贝构造函数 、转换构造函数;下面代码给出了复数类CComplex的多种构造函数以及相关辅助函数;

    1. 普通构造函数

    普通构造函数是最为常见的构造函数,它没有特殊的特点,其函数形参参数可有多个,其函数原型和测试代码如下:

    //普通构造函数原型
    CComplex(int nReal, int nImag);
    
    //测试代码
    //需要指定参数
    CComplex num1(1,1);
    num1.PrintComplex();

    运行结果:

    这里写图片描述

    2. 默认构造函数

    相对于普通构造函数而言,默认构造函数是指用户可以指定实参值,也可以不指定实参值,不指定实参值,系统就使用默认的值,而且默认构造函数只可以有一个,否则有歧义;默认构造函数原型和测试代码如下:

    //默认构造函原型声明
    CComplex();                 //默认构造函数形式1,这里选择形式1
    CComplex(int i=10,int j=10);//默认构造函数形式2
    
    //调用默认构造函数,用户可以不需要指定形参值
    CComplex sum;
    sum.PrintComplex();

    运行结果:

    这里写图片描述

    3. 拷贝构造函数

    拷贝构造函数,也叫做复制构造函数,主要应用于使用一个已存在的对象去初始化一个新对象,使新对象的属性和该对象保持一致

    若用户未定义拷贝构造函数,编译器就自动提供一个默认的复制构造函数,其作用仅是简单地复制类中的每个数据成员;为了安全起见,类设计者需要提供拷贝构造函数;

    拷贝构造函数一般形式:

    类名(const 类名& 对象名)

    形如:CComplex(const CComplex& srcObj)

    在以下三种情况下,拷贝构造函数将被调用;

    1. 建立新对象

    使用一个已存在对象num,初始化即将要被创建的新对象,可以有以下两种形式:

    CComplex num1(num); //形式1
    CComplex num2=num;  //形式2

    运行结果:

    这里写图片描述

    2. 函数形参为类对象

    在函数调用时需要将实参对象完整地传递给形参,系统将默认调用拷贝构造函数,建立一个实参的拷贝,这样形参对象和实参对象将具有相同的属性值;

    需要注意的是,仅形参是按值传递时才会进行对象拷贝,若是传递引用,不会进行对象拷贝,

    形如:

    //按值传递,复制对象
    static void TransByValue(CComplex obj)
    //传递引用,不复制对象
    static void TransByRefence(const CComplex& obj)

    测试代码如下:

    CComplex num(8,8);
    cout << "test case result:
    " << endl;
    
    cout << "test case by refence:
    " << endl;  
    CComplex::TransByValue(num);
    
    cout << "test case by refence:
    " << endl;
    CComplex::TransByRefence(num);

    运行结果:

    这里写图片描述

    3. 函数返回值是类对象

    当一个函数返回值是一个类对象时,在该函数返回调用处时,系统会将函数中的对象复制一份到别的地方,即使返回值没有被使用;

    形如:

    static CComplex GetObj()
    {
      CComplex ret(10,10);  
      return ret;
    }

    测试代码:

    //直接拷贝函数中的对象来初始化新对象num
    CComplex num =  CComplex::GetObj();
    
    //函数返回值进行对象拷贝
    CComplex::GetObj();

    运行结果:

    这里写图片描述

    4. 转换构造函数

    转换构造函数的作用是将一个其他类型的数据转换为一个类的对象。转换构造函数也是一种构造函数,它遵循构造函数的一般原则,我们通常把仅有一个参数的构造函数用作类型转换,所把它称为转换构造函数。

    转换构造函数中的类型数据可以是普通类型,也可以是类类型,其一般形式如下:

    类名(指定类型的数据)

    形如:

    //转换构造函数
    CComplex(int nReal)

    测试代码:

    //定义对象
    CComplex num1(1,1);
    
    cout << "test case result:
    " << endl;
    //num1+2 =》
    //step1:将整型数2转换为CComplex临时对象 调用转换构造函数
    //step2:进行operator+运算符重载
    //step3:运算符重载返回类对象
    CComplex::TransByRefence(num1 + 2);

    运行结果:

    这里写图片描述

    5. 对象拷贝和对象赋值的区别

    对象的赋值是对一个已经存在的对象进行重新赋值,因此必须先定义被赋值的对象,才能进行赋值;

    而对象的拷贝是在从无到有建立一个新对象,并使这个新对象和已有对象完全相同;

    例如:

    CComlex num1(1,1);
    CCompex num2(2,2);
    //对象赋值 使对象num2的值和对象num1一致,调用进行operator=运算符重载
    num2 = num1;
    
    //对象拷贝,利用对象num2创建新对象num3;
    CCompex num3 = num2;

    6. CCompex 类实现代码

    class CComplex
    {
    public:
    
        //普通构造函数
        CComplex(int nReal, int nImag):m_nReal(nReal),m_nImag(nImag)
        {
            cout << "common constructor function" << endl;
        }
        //默认构造函数 默认构造函仅有一个
        CComplex():m_nReal(10),m_nImag(10)
        {
            cout << "default constructor function" << endl;
        }
    
        //拷贝构造函数或者复制构造函数
        CComplex(const CComplex& srcObj)
            :m_nReal(srcObj.m_nReal)
            ,m_nImag(srcObj.m_nImag)
        {
            cout << "copy constructor function" << endl;
        }
    
        //转换构造函数,也可认为是普通构造函数,需要看上下文
        CComplex(int nReal):m_nReal(nReal),m_nImag(0)
        {
            cout << "convert constructor function" << endl;
        }
    
        //赋值操作运算符
        CComplex& operator=(const CComplex& srcObj)
        {
            cout << "operate= function" << endl;
    
            //防止自我赋值,eg:a = a;
            if (this == &srcObj)
           {
               return *this;
           }
    
           this->m_nReal = srcObj.m_nReal;
           this->m_nImag = srcObj.m_nImag;
           return *this;
        }
    
        //析构函数
        ~CComplex(){}
    
    public:
        //+操作运算符  辅助函数,用于说明转换构造函数
        friend CComplex operator+(const CComplex& srcObj1, const CComplex& srcObj2)
        {
            cout << "operate+ function" << endl;
            int nReal = srcObj1.m_nReal+srcObj2.m_nReal;
            int nImag = srcObj1.m_nImag+srcObj2.m_nImag;
            //无名构造函数
            return CComplex(nReal, nImag);
        }
    
        void PrintComplex() const
        {
            cout << "real: " << m_nReal << " " 
                 << "imag: " << m_nImag 
                 << "
    " 
                 <<endl;
        }
        //按值传递,注意不是对象引用
        static void TransByValue(CComplex obj)
        {
          obj.PrintComplex();
        }
    
        static void TransByRefence(const CComplex& obj)
        {
            obj.PrintComplex();
        }
    
        static CComplex GetObj()
        {
            CComplex ret(10,10);
            return ret;
        }
    
    private:
        int m_nReal;
        int m_nImag;
    };
  • 相关阅读:
    vue-常用指令汇总
    vue-插槽和具名插槽
    vue-传值校验
    vue-动态组件
    vue-组件
    zend studio 快捷键收集
    php调试工具firephp
    zend studio插件
    MySQL各个版本区别
    PHP 中 Date 函数与实际时间相差8小时的解决方法
  • 原文地址:https://www.cnblogs.com/jinxiang1224/p/8468239.html
Copyright © 2011-2022 走看看