• C++学习笔记(十二)


    在完成对C语言的学习后,我最近开始了对C++和Java的学习,目前跟着视频学习了一些语法,也跟着敲了一些代码,有了一定的掌握程度。现在将跟着视频做的笔记进行整理。本篇博客是整理C++知识点的第十二篇博客。

    本篇博客介绍了C++的构造函数。

    本系列博客所有C++代码都在Visual Studio 2022环境下编译运行。程序为64位。

    目录

    构造函数

    拷贝构造函数的调用时机

    构造函数调用规则

    深拷贝与浅拷贝

    初始化列表

    类对象作为类成员


    构造函数

    这一部分接着上一篇对构造函数的初步介绍。

    拷贝构造函数的调用时机

    C++中,调用拷贝构造函数的时机通常有这三种情况:

    使用一个已经创建的对象初始化一个新对象。

    用值传递给函数参数传参。

    以值的方式返回局部对象。

    1. #include
    2. using namespace std;
    3. class test {
    4. public:
    5. int age;
    6. test() {
    7. cout << "This is A" << endl;
    8. }
    9. test(const int num) {
    10. age = num;
    11. cout << "This is B" << endl;
    12. cout << "Age = " << age << endl;
    13. }
    14. test(const test& temp) {
    15. age = temp.age;
    16. cout << "This is C" << endl;
    17. cout << "Age = " << age << endl;
    18. }
    19. };
    20. int main(void)
    21. {
    22. test test1;
    23. test test2(10);
    24. test test3(test2);
    25. return 0;
    26. }

    程序中用已经创建的test2初始化一个新的对象test3。

    程序的输出是:

    This is A
    This is B
    Age = 10
    This is C
    Age = 10

    1. #include
    2. using namespace std;
    3. class test {
    4. public:
    5. int age;
    6. test() {
    7. cout << "This is A" << endl;
    8. }
    9. test(const int num) {
    10. age = num;
    11. cout << "This is B" << endl;
    12. cout << "Age = " << age << endl;
    13. }
    14. test(const test& temp) {
    15. age = temp.age;
    16. cout << "This is C" << endl;
    17. cout << "Age = " << age << endl;
    18. }
    19. };
    20. void testfunc(test temp);
    21. int main(void)
    22. {
    23. test test1(10);
    24. testfunc(test1);
    25. return 0;
    26. }
    27. void testfunc(test temp)
    28. {
    29. return;
    30. }

    程序创建了一个test1对象,随后将这个对象作为参数以值传递的方式传递给testfunc函数。testfunc函数只接受这个参数,什么也不执行。因为值传递需要拷贝,所以会执行拷贝构造函数。

    程序的输出是:

    This is B
    Age = 10
    This is C
    Age = 10

    1. #include
    2. using namespace std;
    3. class test {
    4. public:
    5. int age;
    6. test() {
    7. cout << "This is A" << endl;
    8. }
    9. test(const int num) {
    10. age = num;
    11. cout << "This is B" << endl;
    12. cout << "Age = " << age << endl;
    13. }
    14. test(const test& temp) {
    15. age = temp.age;
    16. cout << "This is C" << endl;
    17. cout << "Age = " << age << endl;
    18. }
    19. };
    20. test testfunc(void);
    21. int main(void)
    22. {
    23. test test2 = testfunc();
    24. return 0;
    25. }
    26. test testfunc(void)
    27. {
    28. test test1(10);
    29. return test1;
    30. }

    程序进入main函数后,先执行testfunc函数,testfunc函数创建了一个对象,并将该对象返回main函数,main函数接收后返回。由于返回值也是拷贝,会调用拷贝构造函数。

    程序的输出是:

    This is B
    Age = 10
    This is C
    Age = 10

    构造函数调用规则

    默认情况下,C++编译器会给一个类添加一个默认构造函数,此构造函数无参,函数体为空。还会添加一个默认析构函数,函数体为空。还会添加一个默认拷贝构造函数,对属性进行值拷贝。

    如果已经自定义有参构造函数,那么编译器不再提供默认无参构造函数,但是会提供默认拷贝构造。如果自定义拷贝构造函数,那么编译器不会提供其他构造函数。

    深拷贝与浅拷贝

    浅拷贝就是简单的赋值拷贝操作,深拷贝会在堆区重新申请空间,进行拷贝。

    编译器默认浅拷贝,这样在释放空间时造成重复释放,会导致程序崩溃。如果一个类中有堆区的数据,并且涉及到拷贝,要自己提供拷贝构造函数进行深拷贝。

    1. #include
    2. using namespace std;
    3. class test {
    4. public:
    5. int age;
    6. int* height;
    7. test() {
    8. cout << "This is A" << endl;
    9. }
    10. test(const int numage, const int numheight) {
    11. age = numage;
    12. height = new int(numheight);
    13. cout << "This is B" << endl;
    14. cout << "Age = " << age << endl;
    15. cout << "Height = " << *height << endl;
    16. }
    17. test(const test& temp) {
    18. age = temp.age;
    19. height = new int(*temp.height);
    20. cout << "This is C" << endl;
    21. cout << "Age = " << age << endl;
    22. cout << "Height = " << *height << endl;
    23. }
    24. ~test() {
    25. delete height;
    26. cout << "This is D" << endl;
    27. }
    28. };
    29. int main(void)
    30. {
    31. test test1(20, 170);
    32. test test2(test1);
    33. return 0;
    34. }

    test类提供只输出This is A的无参构造函数。同时提供一个有参构造函数,对age和height进行赋值,age存储在栈区,height存储在堆区,进行了内存开辟。同时输出This is B和成员变量信息。同时提供拷贝构造函数,对height进行了深拷贝,同时输出This is C和成员变量信息。test类的析构函数将height销毁,同时输出This is D。

    main函数用有参构造函数和拷贝构造函数进行初始化。程序的输出是:

    This is B
    Age = 20
    Height = 170
    This is C
    Age = 20
    Height = 170
    This is D
    This is D

    初始化列表

    C++提供了初始化列表,用来初始化属性。语法是:

    构造函数():属性1(值1),属性2(值2),属性3(值3)...{...}

    1. #include
    2. using namespace std;
    3. class test {
    4. public:
    5. int A;
    6. int B;
    7. int C;
    8. test() :A(10), B(15), C(20){}
    9. test(int a,int b,int c) :A(10), B(15), C(20)
    10. {
    11. A = a;
    12. B = b;
    13. C = c;
    14. }
    15. void show() {
    16. cout << "A = " << A << endl;
    17. cout << "B = " << B << endl;
    18. cout << "C = " << C << endl;
    19. }
    20. };
    21. int main(void)
    22. {
    23. test atest;
    24. atest.show();
    25. return 0;
    26. }

    程序创建了test类,test类有成员A,B,C,构造函数中默认初始化值为10,15,20。程序创建了一个类对象,并调用了无参构造函数。程序的输出是:

    A = 10
    B = 15
    C = 20

    如果用构造函数,传入三个0作为参数,程序的输出是:

    A = 0
    B = 0
    C = 0

    类对象作为类成员

    一个类的成员可以是另一个类的一个对象。

    当有其他类的对象作为本类成员时,构造时先构造类对象,后构造自身,析构时相反。

    1. #include
    2. #include
    3. using namespace std;
    4. class Phone {
    5. public:
    6. string brand;
    7. Phone(void) {
    8. cout << "A" << endl;
    9. }
    10. ~Phone(void) {
    11. cout << "Z" << endl;
    12. }
    13. };
    14. class Person {
    15. public:
    16. string name;
    17. Phone phone;
    18. Person(string tempname, string tempbrand){
    19. cout << "a" << endl;
    20. name = tempname;
    21. phone.brand = tempbrand;
    22. }
    23. void show() {
    24. cout << "The name is " << name << endl;
    25. cout << "The phone is " << phone.brand << endl;
    26. }
    27. ~Person() {
    28. cout << "z" << endl;
    29. }
    30. };
    31. int main(void)
    32. {
    33. Person people("Allen", "Apple");
    34. people.show();
    35. return 0;
    36. }

    程序提供了Phone类,有一个成员变量brand,构造函数输出A,析构函数输出Z。程序还有Person类,有一个成员变量是字符串name,另一个成员变量是Phone类对象phone。Person类的带参构造函数输出a,同时对成员变量进行赋值。析构函数输出z,show函数输出成员变量信息。main函数中实例化Person类对象并执行此对象的show函数。

    程序的输出是:

    A
    a
    The name is Allen
    The phone is Apple
    z
    Z

  • 相关阅读:
    12. Spring源码篇之创建Bean逻辑doCreateBean
    数据分析案例-基于sklearn随机森林算法探究影响预期寿命的因素
    maven的进阶学习
    运维知识点-MySQL从小白到入土
    linux部署校园网绕过53端口服务脚本
    移动设备软件开发-广播机制
    数据结构与算法--排序算法复习
    灵性图书馆:好书推荐-《新世界:灵性的觉醒》
    抓包工具charles安装使用
    NAT模式 LVS负载均衡群集部署
  • 原文地址:https://blog.csdn.net/m0_71007572/article/details/126291876