c++构造、析构函数的复习整理

一、构造函数

1、构造函数定义

构造函数函数名与类名相同,无返回值类型(void也不可以),在创建对象时自动执行。

#include <iostream>
using namespace std;

class Person{
private:
    char *m_name;
    int m_age;

public:
    //声明构造函数
   Person(char *name, int age);
    //声明普通成员函数
    void show();
};

//定义构造函数
Person::Person(){
    m_name="小孔";
    m_age =20;
}
Person::Person(char *name, int age){
    m_name = name;
    m_age = age;
}
//定义普通成员函数
void Person::show(){
    cout<<m_name<<"\t"<<m_age<<"\t"<<endl;
}

int main(){
    //创建对象时向构造函数传参,调用带参构造
    Person p1("小刘", 15);
    p1.show();
    //创建对象时向构造函数传参
    Person *p2 = new Person("小王", 16);
    p2 -> show();
    //调用无参构造
    Person p3;
    p3.show();

    return 0;
}

构造函数应为共有属性,否则在创建对象时就无法调用该构造函数。

构造函数的作用是给类中的成员赋值,调用该构造函数,只需要在创建对象的同时传参赋值,就像上例创建的对象p1,p2.只不过在栈上创建对象时,实参位于对象名后面,在堆上创建对象时,实参位于类名后面。

2、函数重载

构造函数是可以重载的,就像上例中的构造函数重载,一个该有形参,一个没有形参。
构造函数的调用是强制性的,**一旦在类中定义了构造函数,那么创建对象时就一定要调用,不调用是错误的。**如果有多个重载的构造函数,那么创建对象时提供的实参必须和其中的一个构造函数匹配,这也就意味着,创建对象时只有一个构造函数会被调用。
在调用带形参的函数时,需要在创建对象时,传递实参;而在调用没有参数的构造时,可以直接创建对象,并且不用加(),这就表示调用的是不带参数的构造。

3、默认构造函数

在c++类中会存在着一个默认构造函数,如果程序员在类的成员中没有编写构造函数,那么系统会自动生成空的构造函数体,尽管这个函数不执行任何操作。
一个类必须有构造函数,要么用户自己定义,要么编译器自动生成。
如果用户自己定义了构造函数,那么编译器便不再自动生成构造函数。

4、构造函数初始化列表

#include <iostream>
using namespace std;

class Person{
private:
    char *m_name;
    int m_age;

public:
    Person(char *name, int age);
    void show();
};

//采用初始化列表
Person::Person(char *name, int age): m_name(name), m_age(age) {
   
}
void Person::show(){
    cout<<m_name<<m_age<<endl;
}

int main(){
    Person p1("小王", 15);
    p1.show();
    Person *p2 = new Person("小美",16);
    p2 -> show();

    return 0;
}

初始化列表的作用是对类内的成员变量进行初始化,写法如上例,是在函数首部与函数体之间添加了一个冒号:,随后用类内成员(形参)的写法,表示将形参值传递给该类内成员。初始化列表可以用于全部成员变量,也可以只用于部分成员变量,用于部分成员变量时,只需要在:后,写出所要初始化的变量即可。
成员变量的初始化顺序与初始化列表中列出的变量的顺序无关,它只与成员变量在类中声明的顺序有关。

初始化列表还有一个作用是给const成员变量赋值,初始化 const 成员变量的唯一方法就是使用初始化列表。

二、 析构函数

创建对象时系统会自动调用构造函数进行初始化工作,同样,销毁对象时系统也会自动调用一个函数来进行清理工作,这个函数就是析构函数。

#include<iostream>
using namespace std;

class student
{
private:
 int m_a;
 int m_b;
public:
 student(int a,int b);
 ~student();
};
student::student(int a, int b): m_a(a), m_b(b){}

student::~student()
{
 cout << m_a << "\t" << m_b << endl;
}

int main()
{
 student stu(1,2);
 
 system("pause");
 return 0;
}

上例可见析构函数的形式:~类名(){}

析构函数没有参数,不能被重载,一个类只能有一个析构函数。如果用户没有定义,编译器会自动生成一个默认的析构函数。

析构函数的调用条件:
在所有函数之外创建的对象是全局对象,它和全局变量类似,位于内存分区中的全局数据区,程序在整体结束执行时会调用这些对象的析构函数。
在栈区系统开辟的内存,系统会自动释放并调用析构函数。
在堆区手动开辟的内存,手动delete释放时,才会调用析构函数

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章