栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

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

前言构造函数

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

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

前言

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

构造函数

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

声明和定义构造函数

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

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

// declare_class.h
#ifndef DECLARE_CLASS_H
#define DECLARE_CLASS_H

class SimpleClass{
	private:
		int a_;
	public:
		SimpleClass(int);
		void set(int);
		int get();
		
		void add(int x) { // inline method
			a_ += 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_H

class SimpleClass{
	private:
		int a_;
	public:
		SimpleClass(int a=0);
		void set(int);
		int get();
		
		void add(int x) { // inline method
			a_ += x;
		}
		
		~SimpleClass();
};

#endif

第二种方法示例如下:

// declare_class.h
#ifndef DECLARE_CLASS_H
#define DECLARE_CLASS_H

class SimpleClass{
	private:
		int a_;
	public:
		SimpleClass(int);
		SimpleClass();
		void set(int);
		int get();
		
		void add(int x) { // inline method
			a_ += x;
		}
		
		~SimpleClass();
};

#endif
// define_class_method.cpp
#include "declare_class.h"

SimpleClass::SimpleClass(){
	a_ = 0;
}
使用默认构造函数

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

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

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

析构函数

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

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

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

// declare_class.h
#ifndef DECLARE_CLASS_H
#define DECLARE_CLASS_H

class SimpleClass{
	private:
		int a_;
	public:
		SimpleClass(int a=0);
		void set(int);
		int get();
		
		void add(int x) { // inline method
			a_ += x;
		}
		
		~SimpleClass();
};

#endif

~SimpleClass()是其析构函数。

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

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

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

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

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

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

对象的列表初始化

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

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

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

后记

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/738752.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号