C++面向对象(2)

类的构造函数(Constructor)和析构函数(Destructor)

<iframe src="http://open.iqiyi.com/developer/player_js/coopPlayerIndex.html?vid=c5d7868e19457dd682738eee9b4b05af&tvId=11980807509&accessToken=2.f22860a2479ad60d8da7697274de9346&appKey=3955c3425820435e86d0f4cdfe56f5e7&appId=1368&height=50%&width=100%" frameborder="0" allowfullscreen="true" width="100%" height="100%"></iframe>

  • 构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。构造函数的名称与类的名称是完全相同的,并且不会反回任何类型,也不会反回void。
  • 析构函数也是类的一种特殊的成员函数,它会在每次删除所创建的对象时执行。函数名称与类的名称完全相同,只是在前面加了个~波浪线作为前缀,它不会返回任何值,也不能带有任何参数。

1.构造函数(Constructor)

  当我们定义一个类的对象时,系统就会自动调用它,进行专门的初始化对象用。如果我们没有定义构造函数,系统会默认生成一个默认形式,隐藏着的构造函数,这个构造函数的函数体是空的,它不具有任何功能。

#include<iostream>
#include<Cstring>
using namespace std;

class Student
{
    private:
    int num;
    char name[100];
    int score;
    public:
    Student(int n,char *str,int s);
    int print();
    int Set(int n,char *str,int s); 
};

Student::Student(int n,char *str,int s)//定义了一个带默认参数的构造函数 
{
    num=n;
    strcpy(name,str);
    score=s;
    cout<<"Constructor"<<endl; 
}

int Student::print()
{
    cout<<num<<" "<<name<<" "<<score;
    return 0;
}

int Student::Set(int n,char *str,int s)
{
    num=n;
    strcpy(name,str);
    score=s;
}

int main()
{
    Student A(1700710135,"yeshan",99);
    A.print();
    
    //Student C;这样定义对象会报错,因为我们在类中定义了一个带默认参数的构造函数 
    cout<<endl;
     
    Student B(1700710134,"xu jie",100);
    B.print();
    return 0;
}
image

<font color="green">由于在程序中定义了一个带默认参数的构造函数,则系统不会再自动生成,这个时候定义对象时也要传入三个默认初始值,因为构造函数可以重载,可以有多个兄弟,系统会找最匹配的一个函数</font>

2.析构函数(Destructor)

 对象销毁时自动调用的一个函数,析构函数不能重载,一个类只能有一个析构函数,析构函数有助于跳出程序前释放内存。

#include<iostream>
#include<Cstring>
using namespace std;
class Student
{
    private:
    int num;
    char name[100];
    int score;
    public:
    Student(int n,char *str,int s);
    ~Student();
    int print();
    int Set(int n,char *str,int s); 
};

Student::Student(int n,char *str,int s)//构造函数 
{
    num=n;
    strcpy(name,str);
    score=s;
    cout<<num<<" "<<name<<" "<<score<<" ";
    cout<<"Constructor"<<endl;
} 

Student::~Student()//析构函数 
{
    cout<<num<<" "<<name<<" "<<score<<" ";
    cout<<"destructor"<<endl;
}

int Student::print()
{
    cout<<num<<" "<<name<<" "<<score<<endl;
    return 0;
}

int Student::Set(int n,char *str,int s)
{
    num=n;
    strcpy(name,str);
    score=s;
}
int main()
{
    Student A(100,"dot",11);
    Student B(101,"cpp",12);
    return 0;
}
image

<font color="green">对象A和B的构造函数的调用顺序以及构造函数的调用顺序,完全相反!原因在于A和B对象同属局部对象,也在栈区存储,也遵循“先进后出”的顺序!</font>

拷贝构造函数

拷贝构造函数是一种特殊的构造函数,具有单个形参,该形参(常用const修饰)是对该类类型的引用。
它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。
当定义一个新对象并用同一个类型的对象对它进行初始化时,将显示使用拷贝构造函。
只包含类类型成员或内置类型(但不是指针类型)成员的类,无须显式地定义拷贝构造函数也可以拷贝。

显示定义拷贝构造函数的情况:
类有数据成员是指针;
有成员表示在构造函数中分配的其他资源
#include<iostream>
using namespace std;

class Age
{
    public:
        int GetAge(void);
        Age(int age);           //Constructor
        Age(const Age& A);      //Copy Constructor
        ~Age();                 //Desconstructor
    private:
        int *ptr;
};

Age::Age(int age)
{
    cout<<"调用构造函数"<<endl;
    ptr = new int;//为指针分配内存
    *ptr = age; 
}

Age::Age(const Age& A)
{
    cout<<"调用拷贝构造函数,并为指针ptr分配内存"<<endl;
    ptr = new int;
    
    *ptr = *A.ptr;   //拷贝值 
}

Age::~Age()
{
    cout<<"释放内存"<<endl;
    delete ptr;
} 

int Age::GetAge(void)
{
    return *ptr; 
}

void print_age(Age A)
{
    cout<<"the age: "<<A.GetAge()<<endl; //这里也调用了拷贝构造函数
}
int main()
{
    Age member_1(10);
    
    Age member_2(member_2);//相当于Age member_2 = member_1;
    
    return 0;   
} 
image
image

image
image
image

<font color="red">成员变量中加一个了指针成员,初始化中需要动态开辟内存,如果不自定义拷贝构造函数,而是用默认生成的,则会出现极大的安全隐患。
默认的拷贝构造函数仅仅是进行数值赋值,并不能为指针开辟内存空间。相当于代码This->str=str.本质上也就是两个指针指向了一块堆空间。程序结束回收对象的时候,会调用自己的析构函数,释放这块内存空间,由于两个对象要调用两次,即delete两次,就会出现错误</font>
<p align="right"><font size=4>引自</font></p>

C++中的this指针

对象中隐藏的指针

  • 每一个对象都能通过this指针来访问自己的地址。this指针是所有成员函数额隐含参数。因此在成员函数内部,它可以用来指向调用的对象。
  • 如果程序中有多个属于同一类的对象,因成员函数的代码仅有一份,所以为了区分它们是哪个对象调用的成员函数,编译器也是转化成this->成员函数这种形式来使用的。
  • 友元函数没有this指针,因为友元不是类的成员。只有成员函数才有this指针。
#include<iostream>
using namespace std;

class Age
{
    public:
        Age(int your_age=18)  //Constructor function 
        {
            cout<<"Constructor now"<<endl; 
            age=your_age;
        }
        int GetAge()
        {
            return age;
        }
        int compare(Age member)
        {
            return this->GetAge()>member.GetAge();   //看这里 
        }
    private:
        int age;
};

int main()
{
    Age member_1(20),member_2(24);
    
    if(member_1.compare(member_2))
    {
        cout<<"member_1 is older than member_2"<<endl;
    }
    else
    {
        cout<<"member_1 is younger than member_2"<<endl;
    }
}
image

关键字new和delete

  1. new(新建)用于新建一个对象。new 运算符总是返回一个指针。由 new 创建。
  2. delete(删除)释放程序动态申请的内存空间。delete 后面通常是一个指针或者数组 [],并且只能 delete 通过 new 关键字申请的指针。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • 1.C和C++的区别?C++的特性?面向对象编程的好处? 答:c++在c的基础上增添类,C是一个结构化语言,它的重...
    杰伦哎呦哎呦阅读 9,476评论 0 45
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy阅读 9,504评论 1 51
  • 先妣于2018年1月5日驾鹤西去,走时面目慈祥,宛若酣睡。见微信群发上来的母亲抢救视频,顿时泪流满面,失声怮哭。彼...
    李文晏语阅读 2,034评论 2 6
  • 下水道堵了,请五金店老板过来通。 疏通后,张口要200。我瞬间懵逼了,这不是明抢嘛,整个过程不过半小时,老娘辛辛苦...
    Yassinia阅读 279评论 0 1
  • 读书之道——精读 一直以来都自诩是阅读高手,因为读书速度比较快。很多时候,别人一两星期读完的书,我已经在一两天内读...
    Herplus王莹阅读 112评论 0 0