欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

C++学习十三、类(2)构造函数,析构函数

时间:2023-05-31
C++学习 十三、类 (2)构造函数,析构函数

前言构造函数

声明和定义构造函数使用构造函数默认构造函数使用默认构造函数 析构函数赋值与初始化

对象赋值对象的列表初始化 后记 前言

本篇继续类与对象,构造函数和析构函数。

构造函数

类的构造函数被用于对象初始化。构造函数也属于类方法。

声明和定义构造函数

构造函数的定义与其它类方法相同,即在类声明中声明构造函数,类方法定义中定义构造函数。

构造函数的名字与类名相同,并且没有返回类型,示例如下:

// declare_class.h#ifndef DECLARE_CLASS_H#define DECLARE_CLASS_Hclass SimpleClass{private:int a_;public:SimpleClass(int);void set(int);int get();void add(int x) { // inline methoda_ += x;}~SimpleClass();};#endif

SimpleClass(int)是类SimpleClass的构造函数声明,下面提供其定义:

// define_class_method.cpp#include "declare_class.h"SimpleClass::SimpleClass(int a) {a_ = a;}

注意:定义构造函数时,容易出现的问题是形参名与类成员数据名冲突。形参名不能与类成员名相同。

使用构造函数

可以采用显式和隐式的方法来调用构造函数初始化对象,示例如下:

// main.cpp#include "declare_class.h"void main(){SimpleClass sc1(1);SimpleClass sc2 = SimpleClass(2);SimpleClass* psc = new SimpleClass(0);}

隐式调用构造函数初始化sc1,初始化语句中没有明确指出构造函数名。
显式调用构造函数初始化sc2,初始化语句直接指出了构造函数名。

也可以使用new为对象分配动态内存时初始化*psc。

注意:构造函数是用于创建对象的,已被创建的对象不能调用构造函数。

默认构造函数

如果希望创建对象时不显式提供初始值,则需要默认构造函数。

当一个类中没有定义任何构造函数时,编译器将自动提供一个默认构造函数,类似于:

SimpleClass::SimpleClass(){}

此时创建的对象不会进行初始化:

SimpleClass sc; // uninitialized

如果定义了构造函数,则编译器不再提供默认构造函数。例如使用declare_class.h声明的类时,下面的对象创建语句将报错:

#include "declare_class.h"void main(){SimpleClass sc; // error!}

由于没有默认构造函数,编译器将报error: no matching function for call to 'SimpleClass::SimpleClass()'。

因此,定义了其它构造函数时,需要手动提供默认构造函数。

一般而言,要避免创建未初始化的对象。因此,通常有两种提供默认构造函数的方法:①定义所有参数带默认值的构造函数。②重载一个无参的默认构造函数。

第一种方法示例如下:

// declare_class.h#ifndef DECLARE_CLASS_H#define DECLARE_CLASS_Hclass SimpleClass{private:int a_;public:SimpleClass(int a=0);void set(int);int get();void add(int x) { // inline methoda_ += x;}~SimpleClass();};#endif

第二种方法示例如下:

// declare_class.h#ifndef DECLARE_CLASS_H#define DECLARE_CLASS_Hclass SimpleClass{private:int a_;public:SimpleClass(int);SimpleClass();void set(int);int get();void add(int x) { // inline methoda_ += x;}~SimpleClass();};#endif// define_class_method.cpp#include "declare_class.h"SimpleClass::SimpleClass(){a_ = 0;}

使用默认构造函数

同样,可以显式和隐式调用默认构造函数:

SimpleClass sc; // implicitlySimpleClass sc = SimpleClass(); // explicitly

注意:默认构造函数在隐式调用时不能使用括号,否则就变成了函数声明。

析构函数

对象达到生命周期时,在销毁前自动调用析构函数进行空间清理。

析构函数也是类方法,并且和构造函数一样没有返回类型。但析构函数没有参数。并且一个类只能有一个析构函数。

析构函数名是在类名前加一个~,仍然以SimpleClass类为例:

// declare_class.h#ifndef DECLARE_CLASS_H#define DECLARE_CLASS_Hclass SimpleClass{private:int a_;public:SimpleClass(int a=0);void set(int);int get();void add(int x) { // inline methoda_ += x;}~SimpleClass();};#endif

~SimpleClass()是其析构函数。

一般而言,不需要显式提供析构函数,编译器将默认提供一个析构函数。

一般而言,不需要显式调用析构函数。

对于静态存储对象,程序结束时会自动调用析构函数;对于自动存储对象,执行完该局部后会自动调用析构函数;对于动态存储对象,当调用delete删除其内存空间时会自动调用析构函数。 赋值与初始化 对象赋值

将一个对象赋值给同类型的另一个变量时,实际上是把一个对象里的每个数据成员复制到另一个对象中:

void main(){SimpleClass sca(1);SimpleClass scb(2);scb = sca; // copy}

需要区分对象赋值和初始化:赋值是给已有的对象进行数据操作;初始化是创建新的对象并对其进行数据操作。

对象的列表初始化

之前的博客已经提过,C++11的一个新特性是列表初始化。这项特性也能用于对象初始化:

void main(){SimpleClass scc {1}; // constructorSImpleClass scd {}; // default constructor}

只要初始化列表中的参数与任何一个该类的构造函数参数列表相符,就能进行列表初始化。

后记

C++中类的基础内容到这就基本结束了。下篇会进入类的进阶内容。

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。