【入土级】详解C++类&对象(中篇)

这篇具有很好参考价值的文章主要介绍了【入土级】详解C++类&对象(中篇)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

前言:类的6个默认成员函数

一, 构造函数

1. 概念

2. 特性

二, 析构函数

2.1 概念

2.2 特性

2.3 牛刀小试 

三, 拷贝构造函数

3.1概念

3. 2 特点

四, 赋值运算符重载

4. 1 运算符重载 

五, const成员函数

六,取地址及const取地址操作符重载

七,练习——实现日期计算器

结语


前言:类的6个默认成员函数

    如果一个类中什么成员都没有,简称为空类。
空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。
默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数。 

 【入土级】详解C++类&对象(中篇)

一, 构造函数

 1. 概念

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

2. 特性

构造函数是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任务 并不是开空间创建对象,而是初始化对象
其特征如下:
  • 1. 函数名与类名相同
  • 2. 无返回值
  • 3. 对象实例化时编译器自动调用对应的构造函数。
  • 4. 构造函数可以重载。(后面拷贝构造函数会体现)
  • 5. 如果存在未自定义默认构造函数,编译器不再生成默认构造函数。 
无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。 注意:无参构造函数、全缺省构造函数、我们没写,编译器默认生成的构造函数,都可以认为是默认构造函数。

下面是一段自定义构造函数的:

#include <iostream>
using namespace std;
class Date
{
public:
	Date(int year = 2023, int month = 5, int day = 9) // 自定义默认构造函数,设置全缺省参数,对数据进行初始化。
	{
		_year = year;
		_month = month;
		_day = day;
	}

private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date z;
	Date z1(2012, 12, 12); // 由于我们自定义构造函数支持带参数设置数据初始化。
	// 接下来,我们注释掉自定义默认构造函数,来测试一下编译器默认自动生成的构造函数。
}

 当我们注释掉我们自定义的构造函数时,我们会发现z对象 的类成员变量,依旧是随机值。这里我们不禁会想,编译器自动生成的默认构造函数似乎什么也没做??

解答:C++把类型分成内置类型(基本类型)和自定义类型。
  • 内置类型就是语言提供的数据类型,如:int/char...;
  • 自定义类型就是我们使用class/struct/union等自己定义的类型。 
看看下面的程序,就会发现编译器生成默认的构造函数会对自定类型成员 _t调用的它的默认成员函数。
#include <iostream>
using namespace std;
class Date
{
public:
	Date(int year = 2023, int month = 5, int day = 9) // 自定义默认构造函数,设置全缺省参数,对数据进行初始化。
	{
		_year = year;
		_month = month;
		_day = day;
	}

private:
	int _year;
	int _month;
	int _day;
};

class Time
{
public:
	Date _t;      // 自定义类型

private:          // 内置类型
	int _hour;
	int _minute;
	int _second;
};
int main()
{
	Time k;
}

调试结果如下: 

  特点:

1. 内置函数不做处理。

2. 自定义类型会调用(自定义类型的)默认构造函数。

【入土级】详解C++类&对象(中篇)

注意:C++11 中针对内置类型成员不初始化的缺陷,又打了补丁,即: 内置类型成员变量在类中声明时可以给默认值

这里我们就有了两种内置成员初始化的方法: 

  • 1. 通过C++补丁初始化;()
  • 【入土级】详解C++类&对象(中篇)
  • 2. 自定义默认构造函数,同时给缺省参数。【入土级】详解C++类&对象(中篇)

二, 析构函数

2.1 概念

通过前面构造函数的学习,我们知道一个对象是怎么来的,那一个对象又是怎么没呢的?
析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的。而 对象在销毁时会自动调用析构函数,完成对象中资源的清理工作

2.2 特性

析构函数是特殊的成员函数,其 特征如下:
  • 1. 析构函数名是在类名前加上字符 ~。
  • 2. 无参数无返回值类型。
  • 3. 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构函数不能重载
  • 4. 对象生命周期结束时,C++编译系统系统自动调用析构函数。

 首先我们来看下面代码:

#include <iostream>
using namespace std;
class Date
{
public:
	Date(int year = 2023, int month = 5, int day = 9)  // 默认构造函数
	{
		_year = year;
		_month = month;
		_day = day;
	}

	~Date()   // 默认析构函数
	{
		_year = _month = _day = 0;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date z;
	return 0;
}

我们将显式析构函数注释掉,让我们测试一下编译器自动生成的默认析构函数的结果,下面的程序我们会看到:编译器生成的默认析构函数,对自定类型成员调用它的析构函数。

#include <iostream>
using namespace std;
class Date
{
public:
	Date(int year = 2023, int month = 5, int day = 9)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	~Date()
	{ 
		cout << "~Date()" << endl;   // 对调用Date的析构函数进行标记
		_year = _month = _day = 0;
	}
private:
	int _year;
	int _month;
	int _day;
};

class Time
{
public:
	Date _t;      // 自定义类型
	~Time()
	{
		cout << "~Time()" << endl; // 对调用Time的析构函数进行标记
	}
private:          // 内置类型
	int _hour = 10;
	int _minute = 10;
	int _second = 10;
};

void func()
{
	Time z;
}
int main()
{
	func();
	return 0;
}

 结果可以看出:【入土级】详解C++类&对象(中篇)

2.3 牛刀小试 

看下面代码,输出顺序是什么? 

class A
{
public:
	A(int a = 0)
	{
      _a = a;
		cout << "A(int a = 0)->" <<_a<< endl;
	}

	~A()
	{
		cout << "~A()->" <<_a<<endl;
	}
private:
	int _a;
};

A aa3(3);

void f()
{
	static int i = 0;
	static A aa0(0);
	A aa1(1);
	A aa2(2);
	static A aa4(4);
}

// 构造顺序:3 0 1 2 4 1 2
// 析构顺序:~2 ~1 ~2 ~1 ~4 ~0 ~3
int main()
{
	f();
	f();
	return 0;
}

核心思路:遵循栈的思路,先进后出

三, 拷贝构造函数

 3.1概念

在现实生活中,可能存在一个与你一样的自己,我们称其为双胞胎。 

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

3. 2 特点

拷贝构造函数也是特殊的成员函数,其 特征如下:
  • 1. 拷贝构造函数是构造函数的一个重载形式
  • 2. 拷贝构造函数的参数只有一个必须是类类型对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用。

下面是会发生无穷递归代码:

class Date
{
public:
	Date(int year = 2023, int month = 5, int day = 9)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	Date(Date b1)  // 正确代码:Date(Date& b1)
	{
		_year = b1._year;
		_month = b1._month;
		_day = b1._day;
	}
private:
	int _year;
	int _month;
	int _day;
};

无穷递归如图:

【入土级】详解C++类&对象(中篇)

 换成类类型引用即可解决无穷递归的问题。 

class Time
{
public:
	Time(int hour = 1 , int minute = 2, int second = 3)
	{
		_hour = hour;
		_minute = minute;
		_second = second;
	}

	Time(const Time& a)
	{
		_hour = a._hour;
		_minute = a._minute;
		_second = a._second;
		cout << "Time(Time& a)" << endl;
	}

	~Time()
	{
		cout << "~Time()" << endl;
	}
private:        
	int _hour;
	int _minute;
	int _second;
};

class Date
{
public:
	Date(int year = 2023, int month = 5, int day = 9)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	Date(const Date& b1)  // 正确代码:Date(Date& b1)
	{
		_year = b1._year;
		_month = b1._month;
		_day = b1._day;
	}

	Time _t;
private:
	int _year;
	int _month;
	int _day;
};
void func()
{
	Date z;
	Date k(z);
}

int main()
{
	func();
	return 0;
}
在编译器生成的默认拷贝构造函数中, 内置类型是按照 字节方式直接拷贝的,而 自定义类型是调用其 拷贝构造函数完成拷贝的。

我们发现,编译器自动生成的拷贝构造函数,足够我们进行值拷贝,那么我们还需要自定义拷贝构造函数吗?

// 这里会发现下面的程序会崩溃掉?这里就需要我们以后讲的深拷贝去解决。
typedef int DataType;
class Stack
{
public:
	Stack(size_t capacity = 10)
	{
		_array = (DataType*)malloc(capacity * sizeof(DataType));
		if (nullptr == _array)
		{
			perror("malloc申请空间失败");
			return;
		}
		_size = 0;
		_capacity = capacity;
	}
	void Push(const DataType& data)
	{
		// CheckCapacity();
		_array[_size] = data;
		_size++;
	}
	~Stack()
	{
		if (_array)
		{
			free(_array);
			_array = nullptr;
			_capacity = 0;
			_size = 0;
		}
	}
private:
	DataType* _array;
	size_t _size;
	size_t _capacity;
};
int main()
{
	Stack s1;
	s1.Push(1);
	s1.Push(2);
	s1.Push(3);
	s1.Push(4);
	Stack s2(s1);  // 等价于, Stack s2 = s1;
	return 0;
}

所以类中如果没有涉及资源申请时,拷贝构造函数是否写都可以;一旦涉及到资源申请时,需要深度拷贝,则拷贝构造函数是一定要写的,否则就是浅拷贝

【入土级】详解C++类&对象(中篇)

四, 赋值运算符重载

4. 1 运算符重载 

      C++为了增强代码的可读性引入了运算符重载运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其 返回值类型与参数列表与普通的函数类似
函数名字为:关键字 operator后面接需要重载的运算符符号
函数原型: 返回值类型 operator操作符(参数列表)
注意:
  • 不能通过连接其他符号来创建新的操作符:比如operator@
  • 重载操作符必须有一个类类型参数
  • 用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不能改变其含义。
  • 作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this。
  • .*  ::   sizeof   ?:   . 注意以上5个运算符不能重载。这个经常在笔试选择题中出现。 

下面有有几个应用例子:

class Time
{
public:
	Time(int hour = 1 , int minute = 2, int second = 3)
	{
		_hour = hour;
		_minute = minute;
		_second = second;
	}

	Time(const Time& a)
	{
		_hour = a._hour;
		_minute = a._minute;
		_second = a._second;
		cout << "Time(Time& a)" << endl;
	}

	bool operator==(const Time& a)   
	{
		return _hour == a._hour &&
			_minute == a._minute &&
			_second == a._second;
	}

	bool operator>(const Time& a)
	{
		return _hour > a._hour &&
			_minute > a._minute &&
			_second > a._second;
	}

   Time& operator=(const Time& a)   // 内成员赋值运算符重载
	{
		_hour = a._hour;
		_minute = a._minute;
		_second = a._second;
		return *this;
	}
	
    ~Time()
	{
		cout << "~Time()" << endl;
	}
private:        // 内置类型
	int _hour;
	int _minute;
	int _second;
};

这里对赋值运算符进行补充;

1.赋值运算符只能重载成类的成员函数不能重载成全局函数  

原因:赋值运算符如果不显式实现,编译器会生成一个默认的。此时用户再在类外自己实现一个全局的赋值运算符重载,就和编译器在类中生成的默认赋值运算符重载冲突了,故 赋值运算符重载只能是类的成员函数
2.用户没有显式实现时,编译器会生成一个默认赋值运算符重载,以值的方式逐字节拷贝。注意:内置类型成员变量是直接赋值的,而自定义类型成员变量需要调用对应类的赋值 运算符重载完成赋值。
既然 编译器生成的默认赋值运算符重载函数已经可以完成字节序的值拷贝了,还需要自己实现吗?当然像日期类这样的类是没必要的。那么下面的类呢?验证一下试试?
// 这里会发现下面的程序会崩溃掉?这里就需要我们以后讲的深拷贝去解决。
typedef int DataType;
class Stack
{
public:
	Stack(size_t capacity = 10)
	{
		_array = (DataType*)malloc(capacity * sizeof(DataType));
		if (nullptr == _array)
		{
			perror("malloc申请空间失败");
			return;
		}
		_size = 0;
		_capacity = capacity;
	}
	void Push(const DataType& data)
	{
		// CheckCapacity();
		_array[_size] = data;
		_size++;
	}
	~Stack()
	{
		if (_array)
		{
			free(_array);
			_array = nullptr;
			_capacity = 0;
			_size = 0;
		}
	}
private:
	DataType* _array;  // 编译器自动生成赋值重载函数的只能是值拷贝,无法做到深拷贝。
	size_t _size;
	size_t _capacity;
};
int main()
{
	Stack s1;
	s1.Push(1);
	s1.Push(2);
	s1.Push(3);
	s1.Push(4);
	Stack s2;
	s2 = s1;
	return 0;
}

 结果分析:【入土级】详解C++类&对象(中篇)

所以,如果类中未涉及到资源管理,赋值运算符是否实现(浅拷贝)都可以;一旦涉及到资源管理则必须要实现(深拷贝)。

五, const 成员函数

将const修饰的“成员函数”称之为const成员函数(比较显著的标志是:成员函数尾巴上有一个const),const修饰类成员函数,实际修饰该成员函数 隐含的this指针,表明在该成员函数中 不能对类的任何成员进行修改。

【入土级】详解C++类&对象(中篇)

让我们看看下面的实例代码吧:

class moss
{
public:
	moss(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << "Print()" << endl;
		cout << "year:" << _year << endl;
		cout << "month:" << _month << endl;
		cout << "day:" << _day << endl << endl;
	}
	void Print() const  // 这就是const成员函数,同上面的Print函数是重载函数。
		// 试试将尾巴上的const 删去,看看会有什么事情发生。
	{
		cout << "Print()const" << endl;
		cout << "year:" << _year << endl;
		cout << "month:" << _month << endl;
		cout << "day:" << _day << endl << endl;
	}
private:
	int _year; // 年
	int _month; // 月
	int _day; // 日
};
void Test3()
{
	moss d1(2022, 1, 13);
	d1.Print();
	const moss d2(2022, 1, 13);
	d2.Print();
}

分析: 

 首先我们已经知道const具有限制权限的功能,比如 int this,如图:【入土级】详解C++类&对象(中篇)

 对本次事例解析:【入土级】详解C++类&对象(中篇)

六,取地址及const 取地址操作符重载

这个比较容易理解,这两个默认成员函数一般不用重新定义 ,编译器默认会生成。 看下面代码:

class Date
{ 
public :
 Date* operator&()
 {
 return this ;
 }
 const Date* operator&()const // 针对的是 被const 修饰的类实例化对象 如:const Date d1;
 {
 return this ;
 }
private :
 int _year ; // 年
 int _month ; // 月
 int _day ; // 日
};
这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需要重载,比如 想让别人获取到指定的内容!

七,练习——实现日期计算器

用C++类编写一个日期计算器,利用今天的运算符重载知识,实现日期+天数,日期-天数,日期-日期的功能。

下面是代码分享:

头文件:

#pragma once

#include<iostream>
using namespace std;
#include <assert.h> 

class Date
{
public:
	// 获取某年某月的天数
	int GetMonthDay(int year, int month)
	{
		// 因为需要频繁调用,所以写成内联函数。
		static int M[13] = { 0,31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
		int day = M[month];
		if (month == 2 &&
			((year % 4 == 0 && year % 100 != 0) ||
				(year % 400 == 0)))
		{
			day++;
		}
		return day;
	}
	// 全缺省的构造函数
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;

		if (!CheckDate())
		{
			cout << "非法日期" << endl;
			exit(-1);
		}
	}

	bool CheckDate()
	{
		if (_month > 12 || _day > GetMonthDay(_year, _month))
		{
			return false;
		}
		else
		{
			return true;
		}
	}
	// 拷贝构造函数
    // d2(d1)
	Date(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}

	// 赋值运算符重载
  // d2 = d3 -> d2.operator=(&d2, d3)
	Date& operator=(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
		return *this;
	}
	// 析构函数, 全是内置函数,没什么好清理的,调用编译器自动生成的就行。
	~Date()
	{
		;
	}
		
	// 日期+=天数
	Date& operator+=(int day);
	// 日期+天数
	Date operator+(int day);
	// 日期-天数
	Date operator-(int day);
	// 日期-=天数
	Date& operator-=(int day);
	// 前置++
	Date& operator++();
	// 后置++
	Date operator++(int);
	// 后置--
	Date operator--(int);
	// 前置--
	Date& operator--();
	// >运算符重载
	bool operator>(const Date& d);
	// ==运算符重载
	bool operator==(const Date& d);
	// >=运算符重载
	bool operator >= (const Date& d);
	// <运算符重载
	bool operator < (const Date& d);
	// <=运算符重载
	bool operator <= (const Date& d);
	// !=运算符重载
	bool operator != (const Date& d);
	// 日期-日期 返回天数
	int operator-(const Date& d);

	int WeekDay()
	{
		Date start(1, 1, 1);
		int LeveDay = 1;
		int day = (*this - start);
		LeveDay += day;
		int WeekDay = LeveDay % 7;
		return WeekDay;
	}
	// 友元函数为外边全局函数拥有调用类成员的权限。
	friend ostream& operator<<(ostream& cou, const Date& a);
	friend istream& operator>>(istream& cin, Date& a);

	void Print()const  // 本身是 Date* const this--是不能修改其指向的this,
		//但可以修改其内容,为了能接受被const Date* const this的对象所以需要缩小权限(方法就是函数名后加const)
		//反正print函数没有修改功能。
	{
		cout << _year << endl;
		cout << _month << endl;
		cout << _day << endl;
	}

private:
	int _year;
	int _month;
	int _day;
};

// 放在全局中可以外部调用重载后的运算符,但放在外面又不能访问类成员,这里会用到后面的友元函数。
// 重载cout输出流
inline ostream& operator<<(ostream& cou,  const Date& a)
{
	cou << a._year << "年" << a._month << "月" << a._day << "日";
	return cou;
}

// 重载cint提取流
inline istream& operator>>(istream& cin, Date& a)
{
	cin >> a._year >> a._month >> a._day;
	assert(a.CheckDate());
	return cin;
}

函数实现源文件:

#define _CRT_SECURE_NO_WARNINGS 1
#include"Date.h"

// 日期+=天数
Date& Date::operator+=(int day)
{
	_day += day;
		while ( Date::GetMonthDay(_year, _month) < _day)
		{
			_day -= Date::GetMonthDay(_year, _month);
			_month++;

			if (_month == 13)
			{
				_month = 1;
				_year++;
			}
		}
	return *this;
}

// 日期+天数     让我们得出结果的临时拷贝,所以可以复用+= ,
// 但有一个缺点是,日期其实已经被污染,不能在原日期下重新调用。
Date Date::operator+(int day)
{
	*this += day;
	Date tmp = *this;
	return tmp;
}


// 日期-天数  //可以复用 -= ,但原日期被修改。
Date Date::operator-(int day)
{
	*this -= day;
	Date tmp = *this;
	return tmp;
}
// 日期-=天数
Date& Date::operator-=(int day)
{
	_day -= day;
	while (_day <= 0)
	{
		_month--;   // 如果_month == 0了,就提取不了对应月份的天数
		if (_month == 0)
		{
			_year--;
			_month = 12;
		}
		_day += Date::GetMonthDay(_year, _month);
	}
	return *this;
}

// 前置++  加完后返回
// 为了区分重载函数前置与后置++,C++做了重载区分,就是后置++增加一个int参数。
Date& Date::operator++()
{
    // 可以进行复用+=
	* this += 1;
	return *this;
}

// 后置++
Date Date::operator++(int)
{
	Date tmp(*this);
	*this += 1;
	return tmp;
}

// 后置--
Date Date::operator--(int)
{
	Date tmp(*this);
	*this -= 1;
	return tmp;
}
// 前置--
Date& Date::operator--()
{
	*this -= 1;
	return *this;
}
// // >运算符重载
bool Date::operator>(const Date& d) 
{
	if ((_year > d._year) ||
		(_month > d._month) ||
		(_day > d._day))
	{
		return true;
	}
	else
	{
		return false;
	}
}
// ==运算符重载
bool Date::operator==(const Date& d)
{
	return _year == d._year &&
		_month == d._month &&
		_day == d._day;
}

// >=运算符重载
bool Date::operator >= (const Date& d)
{
	return (*this > d) || (*this == d);
}

// <运算符重载
bool Date::operator < (const Date& d)
{
	if ((_year < d._year) ||
		((_year <= d._year) && (_month < d._month)) ||
		((_year <= d._year) && (_month <= d._month) && _day < d._day))
	{
		return true;
	}
	else
	{
		return false;
	}
}
// <=运算符重载
bool Date::operator <= (const Date& d)
{
	return (*this < d) || (*this == d);
}
// !=运算符重载
bool Date::operator != (const Date& d)
{
	return _year != d._year &&
		_month != d._month &&
		_day != d._day;
}

// 日期-日期 返回天数  思路:用小的加到大的,计算中间的次数。
int Date::operator-(const Date& d)
{
	int flog = 1;
	Date a1(*this); // 假设a1大
	Date a2(d);
	if (a1 < a2)    // a1小替换为a2
	{
		a1 = d;
		a2 = *this;
		flog = -1;
	}
	int n = 0;
	while (a2 < a1)
	{
		/*if (a2._day == 9 && a2._month == 5)
		{
			int x = 0;
		}*/
		++a2;
		n++;
	}
	return n * flog;
}

测试源文件:

#define _CRT_SECURE_NO_WARNINGS 1

#include"Date.h"

void Test()
{
	const char* WeekRoom[7] = { "周天", "周一", "周二", "周三", "周四", "周五", "周六" };
   
	do
	{
	cout << "------------------------------------" << endl;
	cout << "--------请输入要操作的选项----------" << endl;
	cout << "----1. 日期+天数---2.日期-天数----" << endl;
	cout << "----3. 日期-日期---0.结束程序 --------" << endl;
	cout << "----4.  --------" << endl;
	int opertaton = 0;
	cin >> opertaton;
	Date a1, a2;
	int day;
	switch (opertaton)
	{
	case 1: 
		cout << "-----------"<< endl;
		cin >> a1 >> day;
		cout << (a1 += day) << endl;
		cout << WeekRoom[a1.WeekDay()] << endl;
		break;
	case 2:
		cout << "-----------" << endl;
		cin >> a1 >> day;
		cout << (a1 -= day) << endl;
		cout << WeekRoom[a1.WeekDay()] << endl;
		break;
	case 3:
		cout << "-----------" << endl;
		cin >> a1 >> a2;
		cout << (a1 - a2);
		break;
	case 0:
		cout << "结束程序";
		exit(-1);
	default:
		break;
	}
	} while (true);
}

int main()
{
	Test();
	return 0;
}

结语

本小节就到这里了,感谢小伙伴的浏览,如果有什么建议,欢迎在评论区评论;如果给小伙伴带来一些收获请留下你的小赞,你的点赞和关注将会成为博主创作的动力。文章来源地址https://www.toymoban.com/news/detail-454741.html

到了这里,关于【入土级】详解C++类&对象(中篇)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++初阶】第三站:类和对象(中) -- 类的6个默认成员函数

    目录 前言 类的6个默认成员函数 构造函数 概念 特性 析构函数  概念 特性 拷贝构造函数 概念 特征 赋值运算符重载 运算符重载 赋值运算符重载 const成员 const修饰类成员函数 取地址及const取地址操作符重载 本章总结:         有时候我们写好了一个栈,头脑中第一件事

    2024年02月20日
    浏览(30)
  • 【C++】类和对象②(类的默认成员函数:构造函数 | 析构函数)

    🔥 个人主页: Forcible Bug Maker 🔥 专栏: C++ 目录 前言 类的6个默认成员函数 构造函数 概念 构造函数的特性及用法 析构函数 概念 析构函数的特性及用法 结语 本篇主要内容:类的6个默认成员函数中的 构造函数 和 析构函数 进入到类和对象内容的第二节,上篇博客中介绍了

    2024年04月16日
    浏览(41)
  • 【C++精华铺】5.C++类和对象(中)类的六个默认成员函数

    目录 1. 六个默认成员函数 2. 构造函数 2.1 概念 2.2 默认构造 2.2.1 系统生成的默认构造 2.2.2 自定义默认构造函数  2.3 构造函数的重载 3. 析构函数 3.1 概念  3.2 系统生成的析构函数  3.3 自定义析构函数 4. 拷贝构造 4.1 概念  4.2 默认生成的拷贝构造(浅拷贝)  4.3 自定义拷贝构

    2024年02月13日
    浏览(62)
  • 【C++】类和对象③(类的默认成员函数:拷贝构造函数 | 赋值运算符重载)

    🔥 个人主页: Forcible Bug Maker 🔥 专栏: C++ 目录 前言 拷贝构造函数 概念 拷贝构造函数的特性及用法 赋值运算符重载 运算符重载 赋值运算符重载 结语 本篇主要内容:类的6个默认成员函数中的 拷贝构造函数 和 赋值运算符重载 在上篇文章中我们讲到了类的默认成员函数的

    2024年04月17日
    浏览(37)
  • 【C++练级之路】【Lv.3】类和对象(中)(没掌握类的6个默认成员函数,那你根本就没学过C++!)

    欢迎各位小伙伴关注我的专栏,和我一起系统学习C++,共同探讨和进步哦! 学习专栏 : 《进击的C++》 在C++的学习中,类和对象章节的学习尤为重要,犹如坚固的地基,基础不牢,地动山摇;而默认成员函数的学习,在类和对象的学习里最为重要。所以要 学好C++,学好默认

    2024年02月04日
    浏览(36)
  • 【C++】类和对象详解(类的使用,this指针)

    提示:这里可以添加本文要记录的大概内容: 在计算机编程领域,程序设计的方法论不断演化,从最初的面向过程到如今更为强大而灵活的面向对象。本文将深入探讨C++中关于类和对象的概念,为读者提供对面向对象编程的深刻理解。 提示:以下是本篇文章正文内容,下面

    2024年02月02日
    浏览(31)
  • 【C++】类和对象④(类的默认成员函数:取地址及const取地址重载 | 再谈构造函数:初始化列表,隐式类型转换,缺省值)

    🔥 个人主页: Forcible Bug Maker 🔥 专栏: C++ 目录 前言 取地址及const取地址操作符重载 再谈构造函数 初始化列表 隐式类型转换 explicit 成员变量缺省值 结语 本篇主要内容:类的六个默认成员函数中的 取地址 及 const取地址重载 , 构造函数 初始化列表 , 隐式类型转换

    2024年04月26日
    浏览(36)
  • C++ ------类和对象详解六大默认成员函数

    如果我们定义一个类,然后这个类中什么也没有。那么这里的类就什么也没有吗?其实不然,任何类在里面什么都不写时,编译器都会生成6个默认成员函数。 用户没有显式实现,编译器会生成的成员函数称为默认成员函数。 六个默认成员函数 我们来看一个Date类 观察上述代

    2024年02月15日
    浏览(36)
  • 【C++】类和对象(中篇)

    在往期 类和对象(上篇) 中,我们初步接触了C++中的类和对象,接下来我会和大家分享有关这个知识点更多的内容~ 如果一个类中什么成员都没有,简称为空类。空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成默认成员函数。 默认成员函数:用户

    2024年02月15日
    浏览(41)
  • C++之类和对象的中篇

    𝙉𝙞𝙘𝙚!!👏🏻‧✧̣̥̇‧✦👏🏻‧✧̣̥̇‧✦ 👏🏻‧✧̣̥̇:Solitary_walk       ⸝⋆   ━━━┓      - 个性标签 - :来于“云”的“羽球人”。 Talk is cheap. Show me the code ┗━━━━━━━  ➴ ⷯ 本人座右铭 :   欲达高峰,必忍其痛;欲戴王冠,必承其重。 👑💎💎👑

    2024年04月18日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包