C++学习笔记-构造函数、析构函数、拷贝构造函数

C++ 引入了面向对象的概念,面向对象的思想能够抽象出现实世界的实体,以此解决更加复杂的问题。

类是面向对象的核心,类即是我们对事物抽象之后的产物。C++ 中的类用 class 关键字修饰,后面紧跟着类名 class ClassName

现实世界的实体应该怎么抽象?一部分抽象为是事物的基本属性,一部分抽象为事物的行为。以抽象一只狗为例,狗的基本属性比如说有品种、年龄、毛色、重量等,而它的行为比如说有奔跑、行走、吃东西、叫等。

类中就用变量来表示事物的基本属性,行为则用函数来表示,这就是面向对象思想的核心。在此基础上又有继承、多态等概念,也是为了进一步表现对象与对象之间的关系。

本文讲的是 C++ 中类的构造函数、析构函数以及拷贝构造函数。构造函数区别于普通的函数,是专门用来初始化一个对象的;析构函数则是在函数被销毁时自动调用做善后工作的;拷贝构造函数是另一种初始化类的方法,它直接用类来初始化一个新类。

构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Dog
{
private:
    char name[50];
    int age;

public:
    
    Dog(char *dogName, int dogAge)
    {
        strcpy(name, dogName);
        age = dogAge;
    }

    void initDog(char *dogName, int dogAge)
    {
        strcpy(name, dogName);
        age = dogAge;
    }

    void bark()
    {
        std::cout << name << ": wang wang~~" << std::endl;
    }
};

初始化一个类,需要把参数传给一个类,比如说用 void initDog(char *dogName, int dogAge) 这个方法。C++ 给我提供了一种特殊的函数叫做构造函数就像 Dog(char *dogName, int dogAge) 这样。我们可以用 Dog dog2("bbb", 5); 的方式来调用构造函数并初始化类。

1
2
3
4
5
6
7
class 类名
{
    类名(参数列表)
    {
        构造体
    }
};

构造函数的格式,及注意事项:

  1. 没有返回值
  2. 方法名和类名一致
  3. 构造函数可以重载,让参数列表不同
  4. 默认存在无参构造函数,当自定义构造函数之后无参构造函数失效,此时需要手动定义

构造函数代码示例

析构函数

C++中的类可以定义一个特殊的成员函数清理对象,这个特殊的成员函数叫做析构函数。

1
2
3
4
5
6
7
class 类名
{
    ~类名(参数列表)
    {
        析构体
    }
};

析构函数格式,及注意事项:

  1. 无返回值
  2. 方法名和类名一致,前面有个 ~ 符号
  3. 默认存在一个析构函数
  4. 析构函数不可重载
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Dog
{
private:
    char *name;
    int age;

public:
    
    Dog(char *dogName, int dogAge)
    {
        std::cout << "调用了构造函数." << std::endl;

        name = new char[50];
        strcpy(name, dogName);
        age = dogAge;
    }

    void bark()
    {
        std::cout << name << ": wang wang~~" << std::endl;
    }

    ~Dog()
    {
        std::cout << "调用了析构函数." << std::endl;

        if(name != NULL)
        {
            delete name;
            name = NULL;
        }
    }
};

同样是 Dog 类,和文章开头的 Dog 类别比较有一点小的改动。private 类型变量 name,我将其由字符数组类型更改为了字符指针类型。新的 Dog 类就需要我们在使用的时候为 name 申明一块内存空间,就想我在其构造函数中所做的一样。

与之相对的就是在 Dog 类使用完成之后 free() 之前申明的内存空间。

析构函数代码示例

拷贝构造函数

在第一小节我们看到了普通的构造函数是怎么使用的,之前还提到了构造函数有无参构造函数和有参数构造函数。在没有显示申明构造函数的时候,类自带一个无参构造函数,而当我们显示申明构造函数之后,默认的无参构造函数就失效了,此时如果任然需要无参构造函数,那就需要我们自己显示申明。

接下来再介绍一种构造函数叫做拷贝构造函数,由一个以存在的类来初始化一个新的类就可以使用拷贝构造函数,此时将不由构造器来初始化,而是由拷贝构造器来初始化。

拷贝构造函数与构造函数、析构函数一样,也存在默认的拷贝构造函数,我们可以直接使用如下

1
2
3
4
5
Dog dog("bbb", 5);
dog.bark();

Dog dog2(dog);
dog2.bark();

如果想要自定一个拷贝构造函数格式如下

1
2
3
4
5
6
7
class 类名
{
    类名(const 类名 &dog)
    {
        拷贝构造体
    }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Dog
{
private:
    char name[50];
    int age;

public:
    
    Dog(char *dogName, int dogAge)
    {
        std::cout << "调用了构造函数." << std::endl;

        strcpy(name, dogName);
        age = dogAge;
    }

    Dog(const Dog &dog)
    {

        std::cout << "调用了拷贝构造函数." << std::endl;
        
        strcpy(name, dog.name);
        age = dog.age;
    }

    void bark()
    {
        std::cout << name << ": wang wang~~" << std::endl;
    }
};

深拷贝和浅拷贝

深拷贝与浅拷贝

与结构体一样,类也存在深拷贝和浅拷贝的问题。浅拷贝即拷贝之后两个变量共用一块内存空间,深拷贝即新建一块内存来保存被拷贝的信息。

浅拷贝不是真正意义上的拷贝。在结构体发生浅拷贝时,如果我们释放该结构体,将会影响其他引用该结构体的其他变量。在类中的浅拷贝,如果类中包含的数据元素全部在栈上,浅拷贝也可以满足需求的。但如果堆上的数据,则会发生多次析构行为。

注:关于结构体的深拷贝和浅拷贝可以看我这篇文章 C语言学习笔记-结构体

系统提供的默认拷贝构造器执行的就是浅拷贝操作,如果我们想要将其修改为深拷贝就需要自己手动来实现拷贝构造函数。

1
2
3
4
5
6
7
8
Dog(const Dog &dog)
{
    std::cout << "调用了拷贝构造函数." << std::endl;
    
    name = new char[50];        
    strcpy(name, dog.name);
    age = dog.age;
}
Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值