C++构造函数

来源:互联网 发布:mp4播放软件下载 编辑:程序博客网 时间:2024/06/02 03:12

一、构造函数定义
构造函数(Constructor)是一种特殊的成员函数,它的名字和类名相同,没有返回值,不需要用户调用(用户也不能调用),而是在创建对象时自动执行。构造函数的作用是在创建对象时进行初始化工作。

调用规则:

  • 当类中没有定义任何一个构造函数时,c++编译器会提供默认无参构造函数和默认拷贝构造函数
  • 当类中定义了拷贝构造函数时,c++编译器不会提供无参数构造函数
  • 当类中定义了任意的非拷贝构造函数(即:当类中提供了有参构造函数或无参构造函数),c++编译器不会提供默认无参构造函数
  • 默认拷贝构造函数成员变量简单赋值(浅拷贝)
    -当类中有成员变量是其它类的对象时,首先调用成员变量的构造函数,调用顺序与声明顺序相同;之后调用自身类的构造函数

二、构造函数分类

class Complex {         private :    double m_real;    double m_imag;public:    // 无参数构造函数    // 如果创建一个类你没有写任何构造函数,则系统会自动生成默认的无参构造函数,函数为空,什么都不做    // 只要你写了一个下面的某一种构造函数,系统就不会再自动生成这样一个默认的构造函数,如果希望有一个这样的无参构造函数,则需要自己显示地写出来    Complex(void)    {         m_real = 0.0;         m_imag = 0.0;    }     // 一般构造函数(也称重载构造函数)    // 一般构造函数可以有各种参数形式,一个类可以有多个一般构造函数,前提是参数的个数或者类型不同(基于c++的重载函数原理)    // 例如:你还可以写一个 Complex( int num)的构造函数出来    // 创建对象时根据传入的参数不同调用不同的构造函数    Complex(double real, double imag)    {         m_real = real;         m_imag = imag;              }    // 复制构造函数(也称为拷贝构造函数)    // 复制构造函数参数为类对象本身的引用,用于根据一个已存在的对象复制出一个新的该类的对象,一般在函数中会将已存在对象的数据成员的值复制一份到新创建的对象中    // 若没有显示的写复制构造函数,则系统会默认创建一个复制构造函数,但当类中有指针成员时,由系统默认创建该复制构造函数会存在风险,具体原因请查询有关 “浅拷贝” 、“深拷贝”的文章论述    Complex(const Complex & c)    {        // 将对象c中的数据成员值复制过来        m_real = c.m_real;        m_img  = c.m_img;    }                // 类型转换构造函数,根据一个指定的类型的对象创建一个本类的对象    // 例如:下面将根据一个double类型的对象创建了一个Complex对象    Complex::Complex(double r)    {        m_real = r;        m_imag = 0.0;    }    // 等号运算符重载    // 注意,这个类似复制构造函数,将=右边的本类对象的值复制给等号左边的对象,它不属于构造函数,等号左右两边的对象必须已经被创建    // 若没有显示的写=运算符重载,则系统也会创建一个默认的=运算符重载,只做一些基本的拷贝工作    Complex &operator=(const Complex &rhs)    {        // 首先检测等号右边的是否就是左边的对象本,若是本对象本身,则直接返回        if ( this == &rhs )         {            return *this;        }        // 复制等号右边的成员到左边的对象中        this->m_real = rhs.m_real;        this->m_imag = rhs.m_imag;        // 把等号左边的对象再次传出        // 目的是为了支持连等 eg:    a=b=c 系统首先运行 b=c        // 然后运行 a= ( b=c的返回值,这里应该是复制c值后的b对象)            return *this;    }};

三、浅拷贝和深拷贝

如果没有自定义复制构造函数,则系统会创建默认的复制构造函数,但系统创建的默认复制构造函数只会执行“浅拷贝”,即将被拷贝对象的数据成员的值一一赋值给新创建的对象,若该类的数据成员中有指针成员,则会使得新的对象的指针所指向的地址与被拷贝对象的指针所指向的地址相同,delete该指针时则会导致两次重复delete而出错。下面是示例:

#include <iostream.h>#include <string.h>class Person {public :    // 构造函数    Person(char * pN)    {        cout << "一般构造函数被调用 !\n";        m_pName = new char[strlen(pN) + 1];        //在堆中开辟一个内存块存放pN所指的字符串        if(m_pName != NULL)         {           //如果m_pName不是空指针,则把形参指针pN所指的字符串复制给它             strcpy(m_pName ,pN);        }    }            // 系统创建的默认复制构造函数,只做位模式拷贝    Person(Person & p)        {         //使两个字符串指针指向同一地址位置                 m_pName = p.m_pName;             }    ~Person( )    {        delete m_pName;    }private :    char * m_pName;};void main( ){     Person man("lujun");    Person woman(man);     // 结果导致   man 和    woman 的指针都指向了同一个地址    // 函数结束析构时    // 同一个地址被delete两次}// 下面自己设计复制构造函数,实现“深拷贝”,即不让指针指向同一地址,而是重新申请一块内存给新的对象的指针数据成员Person(Person & chs);{     // 用运算符new为新对象的指针数据成员分配空间     m_pName=new char[strlen(p.m_pName)+ 1];     if(m_pName)              {             // 复制内容            strcpy(m_pName ,chs.m_pName);     }    // 则新创建的对象的m_pName与原对象chs的m_pName不再指向同一地址了}

参考文章:
http://ticktick.blog.51cto.com/823160/194307/

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 铁路办家属证怎么办? 辐射4电梯故障怎么办 车辆被恶意损坏怎么办 汽车划伤见底怎么办 汽车被刀片划伤怎么办 汽车被笔画了怎么办 车被划了一条线怎么办 微信附近人上门被骗怎么办 交通事故认定书不服怎么办 自动挡下坡刹车失灵怎么办 自动挡汽车刹车失灵怎么办 重车刹车失灵怎么办 12306买票待核验怎么办 单位分流不想去怎么办 公司降薪不同意怎么办 浙江违章扣分太多怎么办 船员进出青岛港怎么办 顶楼供暖不热怎么办 成都地铁掉东西怎么办 首都航空航班取消怎么办 猫不舒服躲起来怎么办 狗生病躲起来怎么办 猫咪躲起来了怎么办 vivo手机起热怎么办 vivo手机充电热怎么办 卵泡大于12个怎么办 到排卵期卵泡小怎么办 排卵期卵泡不长怎么办 排卵期没有优势卵泡怎么办 排卵期卵泡发育不好怎么办 成熟卵泡不排卵怎么办 排卵期子宫内膜薄怎么办 双侧卵巢增大怎么办 前列腺3个加号怎么办 武汉华美失败了怎么办 无档案人员怎么办退休 装修欠款不给怎么办 想贷款还信用卡怎么办 国企改私企员工怎么办 吸顶灯灯管坏了怎么办 led灯接触不良怎么办