什么是构造函数

构造函数是初始化类对象的类成员函数。在c++中,当对象被创建时,自动调用构造函数,构造函数是该类的一个特殊成员的函数
构造函数和一般的成员函数有什么不同

  • 构造函数的名称和类的名称完全相同
  • 构造函数没有返回类型(包括void)
  • 创建对象的时候自动调用构造函数
  • 如果我们不写构造函数,编译器会自动创建一个没有参数的构造函数,函数主体内什么也没有(默认构造函数)
  • 函数体中不能有return语句

构造函数不但能隐性的调用,也可以显性的调用。 构造函数是可以重载的,即写多个构造函数,它们具有不同的参数表和相同的名称,如果没有参数信息,编译器就认为调用默认构造函数。 抱歉

构造函数

默认构造函数

A类中编译器自动生成的构造函数如下
A(){}
没有参数的构造函数,不论是编译器自动生成的还是自己写的,都称为默认构造函数。
如果写了构造函数,编译器就不会自动生成默认构造函数

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. class A {
  4. public :
  5. int a, b;
  6. A() {
  7. a = 10, b = 20;
  8. }
  9. };
  10. int main() {
  11. A tmp;
  12. printf("%d %d\n", tmp.a, tmp.b);
  13. A *p = new A;
  14. printf("%d %d\n", p->a, p->b);
  15. return 0;
  16. }

输出
10 20 10 20

参数化构造函数

可以将参数传递给构造函数,只需要向任意函数添加参数一样向构造函数里添加参数,用参数进行初始化。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. class A {
  4. public :
  5. int a, b;
  6. A(int x, int y) {
  7. a = x, b = y;
  8. }
  9. };
  10. int main() {
  11. A tmp(10, 20);
  12. printf("%d %d\n", tmp.a, tmp.b);
  13. A *p = new A(30, 40);
  14. printf("%d %d\n", p->a, p->b);
  15. return 0;
  16. }

输出:
10 20
30 40
如果你的构造函数里有参数但你这么创建对象
A tmp;

  1. A tmp; //报错
  2. A *p = new A; //报错
  3. A tmp(10); //可以,相当于tmp(10, 0);
  1. <br />_//报错_ A *p = new A; _//报错_ A tmp(10); _//可以,相当于tmp(10, 0);_ <br />报错是因为上面两条语句均没有涉及到构造函数的参数,因此编译器会认为这两个对象应该用默认构造函数初始化,但 A 类已经有了一个构造函数,编译器不会自动生成默认构造函数,于是 A 类不存在默认构造函数,所以上面两条语句就无法完成对象的初始化,导致编译报错。<br />在对象生成的时候,一定会自动调用一个构造函数对其初始化,对象一旦生成,就再也不会再这个对象上调用构造函数。<br />构造函数并不会为对象分配空间,再对象创建时内存空间已经被分配好,构造函数只负责初始化这段内存空间。<br />构造函数不但能隐性的调用,也可以显性的调用。
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. class A {
  4. public :
  5. int a, b;
  6. A(int x, int y) {a = x, b = y;}
  7. };
  8. int main() {
  9. A tmp = A(10, 20);
  10. printf("%d %d\n", tmp.a, tmp.b);
  11. return 0;
  12. }

看起来这没有什么用

构造函数的重载

构造函数是可以重载的,即写多个构造函数,它们具有不同的参数表和相同的名称,如果没有参数信息,编译器就认为调用默认构造函数。
特点

  • 重载构造函数具有不同的参数表和相同的名称
  • 根据传参个数决定调用哪个构造函数
  • 创建对象时要传参数让编译器知道调用哪个构造函数 ```cpp

    include

    using namespace std; class A { public :
    1. int a, b;
    2. A(int x, int y) {
    3. a = x, b = y;
    4. }
    5. A(int x) {
    6. a = x, b = 1;
    7. }
    8. A() {
    9. a = b = 0;
    10. }
    11. void mul() {
    12. printf("%d\n", a * b);
    13. }
    };

int main() { A a(10, 20); A b(20); A c = 10; //c=10可以视作c(10) A d;
a.mul(), b.mul(), c.mul(), d.mul(); return 0; }

  1. ```cpp
  2. //答案
  3. 200
  4. 20
  5. 10
  6. 0

构造函数能否声明为虚函数

构造函数不能声明为虚函数,析构函数可以声明为虚函数,而且有时是必须声明为虚函数。 不建议在构造函数和析构函数里面调用虚函数。 1 构造一个对象的时候,必须知道对象的实际类型,而虚函数行为是在运行期间确定实际类型的。

进行构造的顺序:
构造时:基类构造函数→对象成员构造函数→派生类本身的构造函数
析构时:派生类本身的析构函数→对象成员析构函数→基类析构函数

示例:

  1. #include <iostream>
  2. using namespace std;
  3. class component
  4. {
  5. public:
  6. component() {cout << "construct component" << endl;};
  7. ~component() {cout<< "destruct component" << endl;};
  8. };
  9. class base
  10. {
  11. public:
  12. base() {cout << "construct base" << endl;};
  13. ~base() {cout << "destruct base" << endl;};
  14. };
  15. class derived
  16. :base
  17. {
  18. public:
  19. derived() {cout << "construct derived" << endl;};
  20. ~derived() {cout << "destruct derived" << endl;};
  21. component c;
  22. };
  23. int main()
  24. {
  25. derived d;
  26. return 0;
  27. }

答案:

  1. construct base
  2. construct component
  3. construct derived
  4. destruct derived
  5. destruct component
  6. destruct base

网址 :c++ 大佬