iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >详解C++之类和对象(2)
  • 280
分享到

详解C++之类和对象(2)

2024-04-02 19:04:59 280人浏览 独家记忆
摘要

目录一.构造函数1.构造函数的定义:2.构造函数的特征:3.构造函数的实现:3.1.系统默认的构造函数3.2无参构造3.3 带参构造二 析构函数1.析构函数的定义2.析构函数的特征三

一.构造函数

1.构造函数的定义:

构造函数 是一个 特殊的成员函数,名字与类名相同 , 创建类类型对象时由编译器自动调用 ,保证每个数据成员都有 一个合适的初始值,并且 在对象的生命周期内只调用一次 。 其实构造函数的作用就是完成成员变量的初始化 ,但不同于C语言的初始化构造函数可以实在创造对象的同时就完成成员变量的初始化。

2.构造函数的特征:

1. 函数名与类名相同。

2. 无返回值。

3. 对象实例化时编译器 自动调用 对应的构造函数。

4. 构造函数可以重载。

3.构造函数的实现:

构造函数的实现主要有三种,

1.当用户没有实现构造函数的话系统会默认创造一个,此时系统会将内置类型的成员变量赋予随机值,而对于自定义类型的成员变量则会调用他们的构造函数。(注:内置类型一般指的是:int char double float等这些定义好的类型,自定义类型指的是:struct这种类型以及class类这种)。

2.当然用户也可以自己实现构造函数,一种为无参构造

3.类一种为带参构造,但是在带参构造中我们使用全缺省构造。我们用代码展示一下:

3.1.系统默认的构造函数

我们可以看到当我们没有在Data类进行函数构造的时系统将会自己默认创建构造函数,对内置类型变量赋予随机值,自定义类型调用自己的构造函数(若自定义类型也没有定义构造函数那么此例子中的_a1和_a2也会被赋予随机值)

3.2无参构造

3.3 带参构造

这里出一个问题对于代码风格造成的问题:成员变量year最后的结果是多少呢?


class A{public:A(int year){year = year;}private:int year;};int main(){A a(20);}

答案是:随机值。那么为什么是随机值呢?这里主要是变量之间它采用了就近原则,所以等式左边的year会直接寻找离他最近的变量所以会将等式右边的year直接赋值给它自己,所以year最后的值就是随机值。

我们继续来说带参的构造函数,我们一般推荐使用的是全缺省的构造函数(注:

无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,三者都可以认为是默认成员函数。

二 析构函数

构造函数时完成对象的初始化,那么一个对象又是怎么样被销毁的呢?

1.析构函数的定义

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

2.析构函数的特征

1. 析构函数名是在类名前加上字符 ~ 。

2. 无参数无返回值。

3. 一个类有且只有一个析构函数。若未显式定义,系统会自动生成默认的析构函数 。

4. 对象生命周期结束时, c++ 编译系统系统自动调用析构函数。

这里我们用栈的例子来说明析构函数的实现以及作用。


class Stack
	{
	public:
		Stack(int capacity = 4)
		{
			_a = (int*)malloc(sizeof(int)*capacity);
			if (_a == nullptr)
			{
				cout << "malloc fail" << endl;
				exit(-1);
			}
			_top = 0;
			_capacity = capacity;
		}
	//析构函数的实现
		~Stack()
		{
			// 像Stack这样的类,对象中的资源需要清理工作,就用析构函数
			free(_a);
			_a = nullptr;
			_top = _capacity = 0;
		}
 	private:
		int* _a;
		int _top;
		int _capacity;
	};

这里是完成构造函数,有自己定义的析构函数的效果。同构造函数一样对于内置成员变量析构函数会置为随机值,而自定义类型则会去调用他们的析构函数。

三 拷贝函数

如果某些时候我们需要去复制一个对象,这样的话我们该怎么样去解决呢?

这里我们就需要引入拷贝函数。那么什么叫做拷贝函数呢?我们应该去怎么实现呢?有什么注意事项呢?这里我们一一来说道。

1.拷贝函数定义

构造函数 : 只有单个形参 ,该形参是对本 类类型对象的引用 ( 一般常用 const 修饰 ) ,在用 已存在的类类型对象 创建新对象时由编译器自动调用 。

2.拷贝函数的特性

1. 拷贝构造函数 是构造函数的一个重载形式 。

2. 拷贝构造函数的参数只有一个且必须使用引用传参,使用传值方式会引发无穷递归调用 。

3. 若未显示定义,系统生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按字节序完成拷 贝,这种拷贝我们叫做浅拷贝,或者值拷贝。

3.拷贝函数的实现

拷贝函数的实现分为两种一种是系统默认,一种是自己定义。我们分别来看其效果


class A 
{
public:
	A() 
	{ 
         _a1 = 1;
		 _a2 = 2;
	}
	~A() 
	{
		cout << "A()" << endl;
	}
private:
	int _a1;
	int _a2;
};
 class Data
{
public:
	
	//Data(int year, int month, int day) 
	//{
	//	_year = year;
	//	_month = month;
	//	_day = day;
	//}
	Data(int year = 2022, 
		int month = 12, 
		int day = 12) 
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
	A a;
};
 int main() 
{
	Data s;
	//拷贝函数的调用
	Data s2(s);
	return 0;
}

调用系统默认生成拷贝函数(注:这里拷贝函数的拷贝对自定义类型和内置类型的成员变量处理都是一致的完成字节序的值拷贝)

图1 调用系统默认生成的拷贝函数

图2 调用用户自己定义的拷贝函数

在这里我们顺便说一下在自定义拷贝函数的时候一定要使用引用不然会出现无限递归例如 Data(Data s){}正确的使用是Data (const Data & s){}其中const是为了保护原数据不被轻易改动。


class A 
{
public:
	A() 
	{ 
         _a1 = 1;
		 _a2 = 2;
	}
	~A() 
	{
		cout << "A()" << endl;
	}
private:
	int _a1;
	int _a2;
};
 class Data
{
public:
	
	//Data(int year, int month, int day) 
	//{
	//	_year = year;
	//	_month = month;
	//	_day = day;
	//}
	Data( const Data &s) 
	{
		_year = s._year;
		_month = s._month;
		_day = s._day;
 	}
	Data(int year = 2023, 
		int month = 12, 
		int day = 12) 
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
	A a;
};
 int main() 
{
	Data s;
	//拷贝函数的调用
	Data s2(s);
	return 0;
}

我们可以发现s2均完整的赋值了s的内容,但是这里真的就没有问题了吗?如果我们使用系统默认生成的拷贝函数成员变量中含有指针那么会出现什么样的问题呢?


class String
{
public:
String(const char* str = "jack")
 {
_str = (char*)malloc(strlen(str) + 1);
strcpy(_str, str);
 }
~String()
 {
cout << "~String()" << endl;
free(_str);
 }
private:
char* _str;
};
int main()
{
String s;
String s1(s);
}

我们可以看到虽然虽然s1拷贝了s的内容但是最后系统还是抛出了错误那么这个错误来自那里呢?

我们看这幅图

这里就是我们之前说的系统默认生成的拷贝函数是浅拷贝,那么怎么去完成深拷贝我们后边在继续讲解。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!

--结束END--

本文标题: 详解C++之类和对象(2)

本文链接: https://www.lsjlt.com/news/156970.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 详解C++之类和对象(2)
    目录一.构造函数1.构造函数的定义:2.构造函数的特征:3.构造函数的实现:3.1.系统默认的构造函数3.2无参构造3.3 带参构造二 析构函数1.析构函数的定义2.析构函数的特征三...
    99+
    2022-11-12
  • 详解C++之类和对象(1)
    目录C语言和C++的一大区别struct和class的区别总结c++类的由来(或者说为什么要增加类):我们知道c语言是面向过程的语言,c++是即面向过程又是面向过程的语言。那么这两个...
    99+
    2022-11-12
  • C++类和对象之多态详解
    目录多态基本概念和原理剖析多态案例1 计算器类纯虚函数和抽象类多态案例2 制作饮品虚析构和纯虚析构多态案例3 电脑组装多态基本概念和原理剖析 多态:多态是C++面向对象的三大特性之一...
    99+
    2022-11-12
  • C++类和对象之封装详解
    目录封装的意义以及示例访问权限公共权限 public保护权限 protected私有权限 privatestruct 和 class的区别成员属性私有化案例1:设计立方体类案例2:点...
    99+
    2022-11-12
  • Java类与对象详解(2)
      this引用 为什么要有this引用 先来看一个日期类的例子: ​public class Date { public int year; public int month; public int day; /...
    99+
    2023-09-01
    java 开发语言
  • C++核心编程之类和对象详解
    目录1.封装1.1封装的意义封装意义一:封装意义二1.2 struct 和 class 区别1.3 成员属性设置为私有总结C++面向对象三大特性:封装、继承、多态 1.封装 1.1封...
    99+
    2022-11-12
  • C++类与对象的详细说明2
    目录类的默认成员函数构造函数概念特性析构函数概念特性拷贝构造函数概念特征赋值运算符重载运算符重载赋值运算符重载取地址及const取地址操作符重载总结类的默认成员函数 每个类中,如果不...
    99+
    2022-11-13
  • C++类和对象基础详解
    目录一、类和对象的基本概念结构化程序设计面向对象的程序设计使用类的成员变量和成员函数二、类和对象基础 类成员的可访问范围构造函数(constructor)基本概念拷贝(复制)构造函数...
    99+
    2022-11-12
  • C++学习笔记之类与对象详解
    目录前言:1.访问限定符:【问题】C++中 struct和class的区别是什么?2.封装【问题】在类和对象的阶段,我们只研究类的封装特性,那什么是封装呢?3.类的定义与声明【问题】...
    99+
    2022-11-12
  • C++之string类对象的容量操作详解
    目录前言1. size返回字符串的有效长度2. length 返回字符串的有效长度3. capacity 返回总空间的大小4. empty 检测是否为空串5. clear 清空有效字...
    99+
    2022-11-12
  • C++类与对象之运算符重载详解
    目录运算符重载加号运算符重载左移运算符重载递增运算符重载递减运算符重载赋值运算符重载关系运算符重载函数调用运算符重载总结运算符重载 运算符重载概念:对已有的运算符重新进行定义,赋予其...
    99+
    2022-11-12
  • C++OOP对象和类的详细讲解
    目录C++OOP对象和类1.预备知识2.抽象和类2.1 数据抽象2.2 类2.3 接口3.C++中的类和对象3.1 C++类的定义3.2 C++对象的定义3.3 C++访问数据成员3...
    99+
    2022-11-12
  • python基础之定义类和对象详解
    定义简单的类 面向对象是更大的封装,在一个类中封装多个方法,这样通过这个类创建出来的对象,就可以直接调用这些方法了! 定义只包含方法的类 在python中,要定义一个只包含方法的类,...
    99+
    2022-11-13
  • 关于C# 类和对象详情
    目录一、对象的定义和创建二、、对象的初始化1. 借助构造函数或使用2. 实例构造函数3. 静态构造三、对象的引用一、对象的定义和创建 定义类对象的方法为: 类名 对象名; 类是...
    99+
    2022-11-12
  • C++面向对象之类和对象那些你不知道的细节原理详解
    目录一、类和对象、this指针二、掌握构造函数和析构函数三、掌握对象的深拷贝和浅拷贝四、类和对象应用实践五、掌握构造函数的初始化列表六、掌握类的各种成员方法及其区别总结一、类和对象、...
    99+
    2022-11-13
  • 【Java】类和对象详解
    文章目录 一、面向对象1.1 什么是面向对象1.2 面向对象与面向过程 二、类的定义和实例化2.1 类的定义2.2 类的创建2.3 类的实例化2.4 类和对象的联系 三、认识 this...
    99+
    2023-10-18
    java 开发语言
  • C++初阶教程之类和对象
    目录类和对象<上>1. 类的定义2. 类的封装2.1 访问限定修饰符2.2 类的封装3. 类的使用3.1 类的作用域3.2 类的实例化4. 类对象的存储5. this 指...
    99+
    2022-11-13
  • C++入门浅谈之类和对象
    目录一、面向过程vs面向对象二、类的限定符及封装三、类的实例化四、this指针五、默认成员函数1. 构造函数2. 析构函数3. 拷贝函数4. 赋值运算符重载总结一、面向过程vs面向对...
    99+
    2022-11-12
  • C++类的定义和对象的创建详解
    目录1、类的定义2、创建对象3、访问类的成员4、使用对象指针前言: 类和对象是 C++ 的重要特性,它们使得 C++ 成为面向对象的编程语言,可以用来开发中大型项目,本节重点讲解类和...
    99+
    2022-11-12
  • c++学习 之 类和对象 public , protected ,private
    前言 在C++中,访问控制修饰符(Access Control Modifiers)用于控制类的成员(成员变量和成员函数)的访问权限。这些修饰符分为三种:public、protected和private。它们定义了成员可以在何处访问,具体如...
    99+
    2023-08-30
    c++ 学习 开发语言
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作