如何全面掌握C++类中构造函数和析构函数的编写技巧与最佳实践?

2026-04-11 22:452阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1770个文字,预计阅读时间需要8分钟。

如何全面掌握C++类中构造函数和析构函数的编写技巧与最佳实践?

一、初步认识构造函数

1. 什么是构造函数?

如何全面掌握C++类中构造函数和析构函数的编写技巧与最佳实践?

要理解构造函数,首先要明白以下六个默认成员函数:

- 默认构造函数- 析构函数- 复制构造函数- 赋值运算符- 移动构造函数- 移动赋值运算符

如下图所示:

构造函数:构造函数是一个特殊的成员函数,用于创建对象时初始化对象的成员变量。

构造函数的特点:

- 构造函数的名字与类名相同- 构造函数没有返回类型,包括void- 构造函数在创建对象时自动调用

例如:

构造函数:`class MyClass { public: MyClass(); }`

一、初步认识构造函数

1.什么是构造函数?

要了解构造函数就要先了解一下,类的6个默认成员函数,如下图:

构造函数:构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,以保证 每个数据成员都有 一个合适的初始值,并且在对象整个生命周期内只调用一次。

通俗一点来理解就是解决我们最烦的初始化问题。相当于在创建对象的时候自动调用或者编译自动生成来进行初始化。

2.构造函数特性

构造函数是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任务并不是开空间创建对象,而是初始化对象。

特征:

  • 函数名和类相同。
  • 没有返回值。
  • 对象实例化时编译器自动调用对应的构造函数。
  • 构造函数可以重载。
  • 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成。
  • 无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。

注意:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为是默认构造函数。

如下示例:

2.1无参显式构造函数

#include<iostream> using namespace std; class A { public: void Print() { cout << "Print()" << endl; } A(){ cout << "调用了A的构造函数" << endl; } private: int _a; }; int main() { A* a=nullptr; a->Print(); A b; return 0; }

2.2有参显式构造函数

有参显式构造,可以把类中成员变量初始化成自己想要的值。

#include<iostream> using namespace std; class A { public: void Print() { cout << _a << endl; } A(int a) { cout << "调用了A的构造函数" << endl; _a = a; } private: int _a; }; int main() { A b(100); b.Print(); return 0; }

其实涉及到传参,那么就会有全缺省和半缺省传参,下面举一个例子

#include<iostream> using namespace std; class A { public: void Print() { cout << _a << endl; cout << _b << endl; } A(int a,int b=100) { cout << "调用了A的构造函数" << endl; _a = a; _b = b; } private: int _a; int _b; }; int main() { A b(100); b.Print(); return 0; }


2.3隐式构造函数

如果想用隐式构造函数来初始化,那么一定不要显式写出构造函数,如果有显示构造函数首先优先执行构造函数。

#include<iostream> using namespace std; class A { public: void Print() { cout << _a << endl; } private: int _a; }; class B { public: void Print() { cout << _a << endl; } private: int _a; }; int main() { A b; b.Print(); return 0; }


我们发现我们不写构造函数,编译会自动生成构造函数,对内置类型(int/char/double/指针等)不做处理,也就是赋成随机值,对自定义类型( struct / class)会去调用他的默认构造。

2.4 C++11的补充补丁

C++11支持了在成员变量声明的时候给默认值,在生成默认构造函数的时候使用。

举一个例子如下:

#include<iostream> using namespace std; class A { public: void Print() { cout << _a << endl; cout << _b << endl; } //A(int a,int b=100) { // cout << "调用了A的构造函数" << endl; // _a = a; // _b = b; //} private: //默认生成构造函数的时候使用 int _a=100; int _b=100; }; int main() { A b; b.Print(); return 0; }

3.构造函数总结

  1. 构造函数一般情况下,有内置类型成员变量,就要考虑自己写构造函数,因为默认的构造函数对内置类型成员变量不处理(部分编译器处理),所以不能用编译器生成的,得自己显式写一个构造函数。
  2. 如果成员变量全部都是自定义类型成员,那么可以考虑让编译器自己生成。

二、初识析构函数

1.什么是析构函数?

析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作。

通俗一点来说就是来进行扫尾,清除资源的占用,防止内存泄漏。(妈妈再也不用担心,内存泄漏咯)

2.析构函数的特性

特性:

  • 析构函数名是在类名前面加上~。
  • 无参数无返回值类型。
  • 一个类只能有一个析构函数。若没有显示定义,系统会自动生成默认的析构函数。注意:析构函数不能重载。
  • 对象生命周期结束时,C++编译系统会自动调用析构函数。

析构函数的例子

#include<iostream> using namespace std; class A { public: void Print() { cout << _a << endl; cout << _b << endl; } A(int a,int b=100) { cout << "调用了A的构造函数" << endl; _a = a; _b = b; } ~A() { cout << "调用了A的析构函数" << endl; } private: //默认生成构造函数的时候使用 int _a=100; int _b=100; }; int main() { A b(100); b.Print(); return 0; }

由上图可以看出来,在对象生命周期快结束的时候,就自动调用了~A()


标签:

本文共计1770个文字,预计阅读时间需要8分钟。

如何全面掌握C++类中构造函数和析构函数的编写技巧与最佳实践?

一、初步认识构造函数

1. 什么是构造函数?

如何全面掌握C++类中构造函数和析构函数的编写技巧与最佳实践?

要理解构造函数,首先要明白以下六个默认成员函数:

- 默认构造函数- 析构函数- 复制构造函数- 赋值运算符- 移动构造函数- 移动赋值运算符

如下图所示:

构造函数:构造函数是一个特殊的成员函数,用于创建对象时初始化对象的成员变量。

构造函数的特点:

- 构造函数的名字与类名相同- 构造函数没有返回类型,包括void- 构造函数在创建对象时自动调用

例如:

构造函数:`class MyClass { public: MyClass(); }`

一、初步认识构造函数

1.什么是构造函数?

要了解构造函数就要先了解一下,类的6个默认成员函数,如下图:

构造函数:构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,以保证 每个数据成员都有 一个合适的初始值,并且在对象整个生命周期内只调用一次。

通俗一点来理解就是解决我们最烦的初始化问题。相当于在创建对象的时候自动调用或者编译自动生成来进行初始化。

2.构造函数特性

构造函数是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任务并不是开空间创建对象,而是初始化对象。

特征:

  • 函数名和类相同。
  • 没有返回值。
  • 对象实例化时编译器自动调用对应的构造函数。
  • 构造函数可以重载。
  • 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成。
  • 无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。

注意:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为是默认构造函数。

如下示例:

2.1无参显式构造函数

#include<iostream> using namespace std; class A { public: void Print() { cout << "Print()" << endl; } A(){ cout << "调用了A的构造函数" << endl; } private: int _a; }; int main() { A* a=nullptr; a->Print(); A b; return 0; }

2.2有参显式构造函数

有参显式构造,可以把类中成员变量初始化成自己想要的值。

#include<iostream> using namespace std; class A { public: void Print() { cout << _a << endl; } A(int a) { cout << "调用了A的构造函数" << endl; _a = a; } private: int _a; }; int main() { A b(100); b.Print(); return 0; }

其实涉及到传参,那么就会有全缺省和半缺省传参,下面举一个例子

#include<iostream> using namespace std; class A { public: void Print() { cout << _a << endl; cout << _b << endl; } A(int a,int b=100) { cout << "调用了A的构造函数" << endl; _a = a; _b = b; } private: int _a; int _b; }; int main() { A b(100); b.Print(); return 0; }


2.3隐式构造函数

如果想用隐式构造函数来初始化,那么一定不要显式写出构造函数,如果有显示构造函数首先优先执行构造函数。

#include<iostream> using namespace std; class A { public: void Print() { cout << _a << endl; } private: int _a; }; class B { public: void Print() { cout << _a << endl; } private: int _a; }; int main() { A b; b.Print(); return 0; }


我们发现我们不写构造函数,编译会自动生成构造函数,对内置类型(int/char/double/指针等)不做处理,也就是赋成随机值,对自定义类型( struct / class)会去调用他的默认构造。

2.4 C++11的补充补丁

C++11支持了在成员变量声明的时候给默认值,在生成默认构造函数的时候使用。

举一个例子如下:

#include<iostream> using namespace std; class A { public: void Print() { cout << _a << endl; cout << _b << endl; } //A(int a,int b=100) { // cout << "调用了A的构造函数" << endl; // _a = a; // _b = b; //} private: //默认生成构造函数的时候使用 int _a=100; int _b=100; }; int main() { A b; b.Print(); return 0; }

3.构造函数总结

  1. 构造函数一般情况下,有内置类型成员变量,就要考虑自己写构造函数,因为默认的构造函数对内置类型成员变量不处理(部分编译器处理),所以不能用编译器生成的,得自己显式写一个构造函数。
  2. 如果成员变量全部都是自定义类型成员,那么可以考虑让编译器自己生成。

二、初识析构函数

1.什么是析构函数?

析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作。

通俗一点来说就是来进行扫尾,清除资源的占用,防止内存泄漏。(妈妈再也不用担心,内存泄漏咯)

2.析构函数的特性

特性:

  • 析构函数名是在类名前面加上~。
  • 无参数无返回值类型。
  • 一个类只能有一个析构函数。若没有显示定义,系统会自动生成默认的析构函数。注意:析构函数不能重载。
  • 对象生命周期结束时,C++编译系统会自动调用析构函数。

析构函数的例子

#include<iostream> using namespace std; class A { public: void Print() { cout << _a << endl; cout << _b << endl; } A(int a,int b=100) { cout << "调用了A的构造函数" << endl; _a = a; _b = b; } ~A() { cout << "调用了A的析构函数" << endl; } private: //默认生成构造函数的时候使用 int _a=100; int _b=100; }; int main() { A b(100); b.Print(); return 0; }

由上图可以看出来,在对象生命周期快结束的时候,就自动调用了~A()


标签: