C++入门(拷贝)构造函数和析构函数

Posted 正在起飞的蜗牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++入门(拷贝)构造函数和析构函数相关的知识,希望对你有一定的参考价值。

1、构造函数和析构函数

(1)构造函数(constructor):字面意思就是构造对象的函数,当我们定义类的对象时调用,可以帮我们完成对象的初始化;
(2)析构函数(destructor):可以看做是构造函数的逆过程,当销毁类的时候调用,做一些收尾的工作;比如:定义类的对象时构造函数申请了动态内存,那在销毁对象时调研员的析构函数中就要释放申请的动态内存,否则就会造成内存泄漏;
(3)构造/析构函数是C++语言自带的回调函数程序员可以在定义类时使用默认的构造/析构函数,或者自己定义构造/析构函数,但是构造/析构函数的调用却不是程序员主动去调用,而是C++语言自动帮我们调用。比如:定义类的对象时就会自动调用构造函数,销毁类的时候就会调用析构函数,程序员只需要定义类或者销毁类,构造/析构函数的调用是自动的;

2、构造函数和析构函数的使用

(1)C++在定义类时会提供默认的构造/析构函数,默认的构造/析构函数可以看做是空函数,什么也没做,如果我们没有需求可以在类中不定义构造/析构函数;
(2)如果我们在类中定义了构造/析构函数,则C++提供的默认构造/析构函数就失效了,只会调用自定义的构造/析构函数;
(3)构造和析构函数不需要返回值类型,构造函数可以带参或不带参,析构函数不带参;
(4)构造函数可以重载(overload),析构函数不需要重载;
(5)构造函数的名字就是类的名字,析构函数的名字是"~ + 类名";

3、为什么需要构造函数和析构函数

(1)在C语言中只有struct没有class,所以C语言没有构造/析构函数的概念,C语言程序员定义struct后,需要手动去给struct结构体成员初始化;
(2)C++是面向对象的语言,class的封装性比struct更好。
(3)比如:class中有个成员变量是指针,如果没有构造/析构函数,则需要定义对象后手动去为指针申请动态内存,在销毁对象前,手动去释放动态内存;现在动态内存的申请/释放可以放到构造/析构函数中,使用class的程序员不必再操心动态内存的申请释放;

4、不使用动态内存的构造/析构函数

4.1、示例代码

#include <iostream>

using namespace std;

class Person
public:
    int age;

    string getName(void) const;

    //构造函数
    Person();
    Person(string myname);
    
	 // 析构函数
    ~Person();	

private:
    string name;    //人的名字
    mutable int getNameCnt; //名字被查询的次数

;


int main(void)

	//定义对象,此时会调用构造函数
	Person *p1 = new Person ("linux");

    cout << "p1.name=" << p1->getName() << endl;
	
    //   销毁对象
    delete(p1);

	return 0;


string Person::getName(void) const

    this->getNameCnt++;
    cout << "getNameCnt=" << this->getNameCnt << endl;
    return this->name;


//  使用参数列表的方式
Person::Person()

        cout << "Person::Person()" << endl;
        this->getNameCnt=0;
;

//  构造函数:使用参数列表的方式
Person::Person(string myname):name(myname)

       //this->name=myname;	//等同于上面参数列表的形式
        cout << "Person::Person(string myname):name(myname)" << endl;
        this->getNameCnt=0;
;

// 析构函数:在没有使用动态内存的情况下,析构函数一般都是空函数
Person::~Person()

      cout << "~Person" << endl;
;

4.2、代码分析

root@ubuntu:# ./app 
Person::Person(string myname):name(myname)
getNameCnt=1
p1.name=linux
~Person

(1)在定义对象时调用了构造函数,调用的是传string形式的,因为构造函数支持函数重载,并且定义定义对象时传入了string的参数;
(2)在销毁对象时调用了析构函数;

5、使用动态内存的构造/析构函数

5.1、示例代码

#include <iostream>

using namespace std;

class Person
public:
    int age;

    string getName(void) const;

    //构造函数
    Person();
    Person(string myname);

     // 析构函数
    ~Person();

private:
    string *name;    //人的名字
    mutable int getNameCnt; //名字被查询的次数

;

int main(void)

    //定义对象,此时会调用构造函数
    Person *p1 = new Person ("linux");

    cout << "p1.name=" << p1->getName() << endl;

    //   销毁对象
    delete(p1);

    return 0;


string Person::getName(void) const

    this->getNameCnt++;
    cout << "getNameCnt=" << this->getNameCnt << endl;
    return *this->name;


//  使用参数列表的方式
Person::Person()

        cout << "Person::Person()" << endl;
        this->getNameCnt=0;
;

//  构造函数
Person::Person(string myname)

        this->name = new string(); //申请动态内存
        
       *this->name=myname;
        cout << "Person::Person(string myname):name(myname)" << endl;
        this->getNameCnt=0;
;

// 析构函数
Person::~Person()

      cout << "[~Person] delete this->name" << endl;
      delete (this->name);	//释放在构造函数中申请的动态内存
;

5.2、代码分析

root@ubuntu:# ./app 
Person::Person(string myname):name(myname)
getNameCnt=1
p1.name=linux
[~Person] delete this->name

(1)上第4节的代码相比,将class中name变量从string类型变成string指针类型;
(2)在构造函数中为string指针申请内存,在析构函数中释放内存;
总结:如果类中使用动态内存,可以在构造函数中申请,在析构函数中释放,使用类的程序员不用再操作内存的申请释放;

6、拷贝构造函数

参考博客:《【C++入门】拷贝构造函数》

7、推荐

我会在C++专栏持续根据更新C++相关的知识点,这里也给大家推荐一款学习C++的神器,我也是在用这一款神器在学习C++。
链接:学习神器跳转
如果你是想入门C++这门语言或者是找C++岗位的工作,都推荐你试试这个网站,里面有针对C++知识点的选择题、编程题,更有C++岗位的面试题

以上是关于C++入门(拷贝)构造函数和析构函数的主要内容,如果未能解决你的问题,请参考以下文章

C++入门拷贝构造函数详解

C++入门拷贝构造函数详解

C++面试之 类string的构造函数拷贝构造函数和析构函数

c++中构造和析构函数

C++的构造拷贝构造和析构的简单总结

CPP_类默认函数:构造函数,拷贝构造函数,赋值函数和析构函数