C++构造/析构/赋值函数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++构造/析构/赋值函数相关的知识,希望对你有一定的参考价值。
在编写C++程序的时候,我们会为特定某一类对象申明类类型,几乎我们申明的每一个class都会有一个或多个构造函数、一个析构函数、一个赋值运算符重载=、以及拷贝构造函数。这些函数控制着类对象的基础操作,确保新定义的对象的初始化、完成对象撤销时的清理工作、赋予对象新值。如果这些函数的操作出错,则会导致严重的后果,所以确保这些函数的操作行为正常是非常重要的。
一、编译器默认生成的函数
如果我们编写一个空类,编译器会为我们默认生成构造函数、析构函数、赋值运算符、拷贝构造函数。
例如当我们定义
class Empty{ };
就好像我们写下了如下代码(红色是编译器默认生成)
class Empty{
public:
Empty(){....} //默认构造函数
Empty(const Empty &rhs){....} //默认拷贝构造函数
~Empty(){....} //默认析构构造函数
Empty& operator=(const Empty &rhs){....} //赋值运算符
Empty* operator&(){...} //取地址运算符
const Empty* operator&() const{...} //取地址运算法的const版本
};
1. 说明:(1)这些函数只有在被调用的时候,才会被编译器创建出来;
(2)四个函数都public且inline的;
(3)如果显示的定义了其中某一个函数,那么编译器就不会生成其对应的默认的版本;
(4)自定义的拷贝构造函数不仅会覆盖默认的拷贝构造函数,同时也会覆盖默认的构造函数,下面的函数class构造函数,不能通过编译
1 class Empty 2 { 3 4 public: 5 Empty(const Empty& e) {} 6 }; 7 8 int main(int argc, char** argv) 9 { 10 Empty a; 11 } 12 // error: no matching function for call to ‘Empty::Empty()‘|
2. 实例:
下面的代码会让编译器创建默认的构造函数 Empty e1; //默认构造函数
Empty e2(e1);//拷贝构造函数
e2 = e1;//赋值运算符
1 #include <iostream> 2 using namespace std; 3 4 class Empty{ 5 6 public: 7 Empty(){cout << "create" << endl;} 8 Empty(const Empty &Copy){ cout << "copy" << endl;} 9 Empty& operator=(const Empty &Assig){cout << "assign=" << 10 endl;} 11 Empty* operator&(){cout << "&" << endl;} 12 const Empty* operator&() const {cout << "&1" << endl;} 13 ~Empty(){cout << "delete" << endl;} 14 }; 15 int main() 16 { 17 Empty *e = new Empty(); // create 18 delete e; //delete 19 Empty e0; //create 20 const Empty e1; //create 21 Empty e2(e1); //copy 22 Empty e3; //create 23 e3 = e1;//assign= 24 cout << &e0 << endl;//& 0x602080 25 const Empty *p = &e1;//&1 26 cout << p << endl; //0x602080 27 return 0; 28 } 29 //e0,e1,e2,e3对象被撤销时候删除 30 delete 31 delete 32 delete 33 delete
二、构造函数
1. 构造函数的作用
构造函数是特殊的成员函数,用来在创建对象时完成对对象属性的一些初始化等操作, 当创建对象时, 对象会自动调用它的构造函数。
2. 默认构造函数
正如第一部分所述,如果没有为一个类显示定义任何构造函数、编译器将自动为这个类生成默认构造函数。默认构造函数将依据变量初始化的规则初始化类中的所有成员:
(1)对于具有类类型的成员,会调用该成员所属类自身的默认构造函数实现初始化;
(2)内置类型成员的初值依赖于对象如何定义,如果对象在全局作用域中定义或定义为静态局部对象,则这些成员将被初始化为0。如果对象在局部作用域中定义,则这些成员没有初始化;
(3)默认构造函数一般适用于仅包含类类型的成员的类;
(4)由于默认构造函数不会初始化内置类型的成员,所以必须显示定义类的构造函数。
1 #include <iostream> 2 using namespace std; 3 class Empty 4 { 5 public: 6 int a; 7 string s; 8 }; 9 10 int main(int argc, char** argv) 11 { 12 Empty a; 13 cout << a.a << endl;//输出a的值随机 14 cout << a.s.size() << endl;//s是类类型被初始化为空串 15 }
3. 构造函数的特点
(1)在对象被创建时自动执行;
(2)构造函数的函数名与类名相同;
(3)没有返回值类型、也没有返回值;
(4)构造函数不能被显式调用;
4. 重载构造函数
可以为一个类申明的构造函数的数量没有限制,只要每个构造函数的形参表示唯一的。定义类对象的时候,实参指定使用哪个构造函数。
以上是关于C++构造/析构/赋值函数的主要内容,如果未能解决你的问题,请参考以下文章
C++初阶第五篇——类和对象(中)(构造函数+析构函数+拷贝构造函数+赋值操作符重载)
C++类和对象(构造函数析构函数拷贝构造函数赋值运算符重载Const成员)详细解读