0基础入门C++之类和对象中篇

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

1.类的6个默认成员函数

通过类和对象上篇的学习,我们知道知道如果一个类中没有成员变量,也没有成员函数,啥也没有,那我们把它叫做空类。
比如 :class Date {};

那么空类中真的什么都没有吗?

并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。

默认成员函数:即用户没有显式实现,编译器自动生成的成员函数称。

0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构

2.构造函数

2.1概念

现在有这样一个类:

class Date
{
public:
	void Init(int year, int month, int day)
	{
	
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << _year << "/"  << _month  << "/"  <<  _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1;
	Date d2;
	d1.Init(2023,9,5);
	d1.Print();

	d2.Init(2023,8,18);
	d2.Print();

	return 0;
}

那对于一个类来说,我们实例化出来对象之后一般会对其进行一个初始化,但是有时候我们可能会忘记初始化,直接就对对象进行一些操作,不初始化直接用可能就会出现问题。

0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构
那么针对以上情况,C++给我们提供一种方法解决这个问题。

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

2.2特性

构造函数是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任务并不是开空间创建对象,而是初始化对象。

其特征如下:

  1. 函数名与类名相同。

也就是说定义好一个类,它的构造函数的函数名就已经确定,跟当前类的类名是相同的。

  1. 无返回值。

要注意这里说的无返回值不是说返回类型是void,而是根本就不写返回类型。

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

通过构造函数我们初始化对象就不用再手动初始化了,实例化对象时编译器会自动调用其对应的构造函数。

  1. 构造函数可以重载。

那么接下来我们就给上面的Date类写一个构造函数。

  Date()
  {
	_year = 1;
    _month = 1;
    _day = 1;

  }
  1. 无参构造函数

0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构
通过上图运行结果我们看出:这次我们并没有调用初始化函数,但是打印出来不是随机值,而是我们在构造函数中给定的值,说明我们实例化对象的时候确实自动调用构造函数进行初始化了。

  1. 带参构造函数
Date(int year, int month, int day)
	   {
		   _year = year;
		   _month = month;
		   _day = day;

	   }

0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构

注意: 如果通过无参构造函数创建对象时,对象后面不用跟括号,否则就成了函数声明.

  1. 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成

也就是说,构造函数不一定非要自己写,如果我们自己没有定义构造函数,编译器会自动生成一个。只不过是无参的。

那编译器会自动生成的话,我们以后是不是就不用自己写构造函数了?

答案是不可以

将上文中自己写的构造函数注释掉,直接运行程序:
0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构
我们可以看到调用编译器自动生成的构造函数是随机值。

实际上这个地方大家可以认为是C++在设计时出现了问题。

C++把类型分成内置类型(基本类型)和自定义类型。内置类型就是语言提供的数据类型,如:int/char...(包括各种指针类型),自定义类型就是我们使用class/struct/union等自己定义的类型
而编译器自动生成的构造函数不会对内置类型进行处理,对于自定义类型会处理,怎么处理?会去调用该自定义类型对应的默认构造函数

我们再看一个例子:

class Time
{
public:
	Time()
	{
		cout << "Time()" << endl;
		_hour = 0;
		_minute = 0;
		_second = 0;
	}
private:
	int _hour;
	int _minute;
	int _second;
};
class Date
{
private:
	// 基本类型(内置类型)
	int _year;
	int _month;
	int _day;
	// 自定义类型
	Time _t;
};
int main()
{
	Date d;
	return 0;
}

这里的Date类它的成员变量里既有内置类型又有自定义类型。
但是我们现在并没有给Date类写构造函数,那我们在main函数里直接拿Date去创建一个对象,它自然就会去调用编译器自动生成的构造函数,那内置类型不做处理,这里还有一个自定义类型Time _t;,对于自定义类型,编译器会自动去调用它对应的默认构造函数。
我们运行一下验证一下结果:
0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构

那难道说内置类型不写构造函数就没法初始化了吗?

注意: C++11 中针对内置类型成员不初始化的缺陷,又打了补丁,即:内置类型成员变量在类中声明时可以给默认值。
0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构
0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构

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

3.析构函数

3.1概念

通过前面构造函数的学习,我们知道一个对象是怎么来的,那一个对象又是怎么没呢的?

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

下面我们举一个例子来帮助大家理解:

typedef int DataType;
class Stack
{
public:
	//构造函数
	Stack(size_t capacity = 4)
	{
		_array = (DataType*)malloc(sizeof(DataType) * capacity);
		if (NULL == _array)
		{
			perror("malloc fail");
			return;
		}
		_capacity = capacity;
		_size = 0;
	}
	void Push(DataType data)
	{
		// CheckCapacity();
		_array[_size] = data;
		_size++;
	}
	
private:
	DataType* _array;
	int _capacity;
	int _size;
};

int main()
{
	Stack s;
	s.Push(1);
	s.Push(2);
	return 0;
}

这里的对象s需要我们自己去销毁吗?
答案是不需要,因为s是定义在栈区上的局部变量,程序结束,它就随着main函数的栈帧自动销毁。
那析构函数的作用是啥呢?完成对象中资源的清理工作,什么意思?
像栈这样的对象,它里面是有在堆上动态开辟的空间,那经过C语言的学习我们都知道,这些空间是需要我们手动去释放的,否则可能会导致内存泄漏。
所以说,析构函数就是来帮我们干这件事情的。

3.2特性

析构函数是特殊的成员函数,其特征如下:

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

一个类定义好之后,它的析构函数的函数名也是确定的,即在类名前面加上“~”。
“~”在C语言中是按位取反,表示它的功能和构造函数是相反的。

  1. 无参数无返回值类型
  2. 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构函数不能重载
  3. 对象生命周期结束时,C++编译系统系统自动调用析构函数。

下面我们就给刚才的栈写一个析构函数

~Stack()
	{
		free(_array);
		_array = NULL;
		_capacity = 0;
		_size = 0;
		
	}


为了方便观察是否自动调用了析构函数我们可以在代码中加入一行打印:
0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构

此时我们main函数里并没有显示调用~Stack函数
0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构
运行结果如下:
0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构

  1. 关于编译器自动生成的析构函数,是否会完成一些事情呢?下面的程序我们会看到,编译器生成的默认析构函数,对自定类型成员调用它的析构函数。
typedef int DataType;
class Stack
{
public:
	//构造函数
	Stack(size_t capacity = 4)
	{
		_array = (DataType*)malloc(sizeof(DataType) * capacity);
		if (NULL == _array)
		{
			perror("malloc fail");
			return;
		}
		_capacity = capacity;
		_size = 0;
	}
	void Push(DataType data)
	{
		// CheckCapacity();
		_array[_size] = data;
		_size++;
	}

	~Stack()
	{
		cout << "~Stack" << endl;
		free(_array);
		_array = NULL;
		_capacity = 0;
		_size = 0;
		
	}


	
private:
	DataType* _array;
	int _capacity;
	int _size;
};

class Date
{
private:
	// 基本类型(内置类型)
	int _year;
	int _month;
	int _day;
	// 自定义类型
	Stack _s;
};

int main()
{
	// Stack s;
	// s.Push(1);
	// s.Push(2);
	Date d1;
	return 0;
}

这里我们没有给Date显式定义析构函数,d1声明周期结束时,就会调用编译器自己生成的默认析构函数,那里面的内置类型不做处理,而自定义类型Stack _s;申请的资源需要清理,编译器自己生成的默认析构函数会调用Stack 类的析构函数:
0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构

  1. 如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数,比如 Date类;有资源申请时,一定要写,否则会造成资源泄漏,比如Stack类。

4.拷贝构造函数

4.1概念

我们再来回顾一下之前创建的日期类:

class Date
{
public:
       Date(int year = 1, int month = 1, int day = 1)
	   {
		   _year = year;
		   _month = month;
		   _day = day;

	   }


	void Print()
	{
		cout << _year << "/"  << _month  << "/"  <<  _day << endl;
	}
private:
	int _year = 1;
	int _month = 1;
	int _day = 1;
};

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

现在有这样一个问题:如果我们现在想再创建一个对象,使这个对象和d1一样,或者说是d1的一份拷贝,应该怎么实现呢?

经过上面的学习,相信老铁们很容易想到,我们想创建一个和d1一样的新对象,可以用d1去初始化创建出来的新对象啊。是不是把构造函数的参数类型设置成类对象的类型就行了。
这就是拷贝构造。

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

4.2 特性

拷贝构造函数也是特殊的成员函数,其特性如下:

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

那么我们现在先来写一个拷贝构造函数:

   Date(Date d)
      {
	      _year = d._year;
	      _month = d._month;
	      _day = d._day;
      }

那这样就可以了吗?
0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构

这里不行的原因是:在之前拷贝构造函数概念中我们提到参数类型必须是类类型对象的引用。
0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构

那为什么必须是类类型对象的引用呢?

  1. 拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错, 因为会引发无穷递归调用。

在这里为什么会引发无穷递归呢?
0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构

此外对一个对象拷贝构造也可以这样写:

0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构

除此之外,我们还需要注意:

拷贝构造函数形参一般用const修饰:
0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构
相信这一点大家不难理解,形参是用来初始化我们新创建的对象的,加个const修饰形参d不会被修改。此外加上const 若传来的参数是const修饰的,我们依然可以接收。

  1. 若未显式定义,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。

那么默认生成的拷贝构造函数是否可靠呢?

这里我们再来看一下日期类:

首先我们将刚才实现的拷贝构造函数注释掉:

class Date
{
public:
       Date(int year = 1, int month = 1, int day = 1)
	   {
		   _year = year;
		   _month = month;
		   _day = day;

	   }

	//    Date(const Date& d)
    //   {
	//       _year = d._year;
	//       _month = d._month;
	//       _day = d._day;
    //   }




	void Print()
	{
		cout << _year << "/"  << _month  << "/"  <<  _day << endl;
	}
private:
	int _year = 1;
	int _month = 1;
	int _day = 1;
};

int main()
{
	// Date d1(2023,9,5);
	// Date d2(2023,8,18);
	//d1.Init(2023,9,5);
	Date d1;
	Date d2(d1);
	Date d3 = d1;
	d1.Print();
	//d2.Init(2023,8,18);
	d2.Print();
    d3.Print();
	return 0;
}

我们看一下结果
0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构

看到这里拷贝构造函数能一直可靠吗?

下面我们再来看一下Stack类:

typedef int DataType;
class Stack
{
public:
	//构造函数
	Stack(size_t capacity = 4)
	{
		_array = (DataType*)malloc(sizeof(DataType) * capacity);
		if (NULL == _array)
		{
			perror("malloc fail");
			return;
		}
		_capacity = capacity;
		_size = 0;
	}
	void Push(DataType data)
	{
		// CheckCapacity();
		_array[_size] = data;
		_size++;
	}

	~Stack()
	{
		cout << "~Stack" << endl;
		free(_array);
		_array = NULL;
		_capacity = 0;
		_size = 0;
		
	}


	
private:
	DataType* _array;
	int _capacity;
	int _size;
};



int main()
{
	Stack s;
	s.Push(1);
	s.Push(2);
	Stack s2(s);
	return 0;
}

对于Stack类我们也没有写拷贝构造函数,我们运行一下看一下结果:
0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构
会发现这里程序挂了, 那这里挂了的原因是什么呢?

其实这里根本原因就是出现在特性3上。

在特性3中有这样一句话:
0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构
在这里其实就是对逐个成员变量依次进行拷贝,里面存的是啥就把啥拷过去。

我们来对比一下Date类和Stack这两个类的拷贝:

对于Date类,浅拷贝是没有问题的。
0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构
一共12字节的内容依次拷贝过去就行

对于Stack类浅拷贝是存在问题的:
0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构
在这里出了作用域就会调用析构函数,而两个s1和s2中指针指向的空间就会被free两次,同样的我们在s1中入栈数据,s2里面就也有数据了(因为它俩用的是同一块空间),然后如果我们再用st2去入栈数据,此时s1_size前面已经++过,但是s2_size前面还是0,这样s2入的数据就把之前s1入的数据给覆盖了。

注意:
这里是s2先析构,我们知道s1和s2都是在栈上的(栈区),那栈区之所以叫栈区就是因为它在这个地方栈帧的建立也是遵循先进后出的这个顺序的,即后定义的会先进行析构。s2先析构,那堆上的这块空间就被释放了,但是接下来st也会进行它的析构,而此时虽然s1还保留了这块空间的地址,但是这块空间已经被释放,所以s1就是个野指针了。
所以为什么程序崩溃了,就是我们这里对野指针进行free了
0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构

因此:

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

  1. 拷贝构造函数典型调用场景:

使用已存在对象创建新对象
函数参数类型为类类型对象
函数返回值类型为类类型对象

5.赋值运算符重载

5.1运算符重载

C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其 返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。
函数名字为: 关键字operator后面接需要重载的运算符符号。
函数原型: 返回值类型 operator操作符(参数列表)

下面我们依旧以日期类为例:

class Date
{
public:
       Date(int year = 1, int month = 1, int day = 1)
	   {
		   _year = year;
		   _month = month;
		   _day = day;

	   }

	void Print()
	{
		cout << _year << "/"  << _month  << "/"  <<  _day << endl;
	}
private:
	int _year = 1;
	int _month = 1;
	int _day = 1;
};

int main()
{
	Date d1(2023,9,5);
	Date d2(2023,8,18);

	d1.Print();
	d2.Print();

	return 0;
}

现在有两个对象d1,d2,大家思考一个问题,现在我们想比较这两个对象是否相等,要怎么实现呢?相信大家很容易想到用一个函数实现:

bool Equal(const Date& x1, const Date& x2)
{
	//...
}

但是在C++引入运算符重载之后呢,就使得我们还能够这样去实现:

bool operator==(const Date& d1, const Date& d2)
{
	return d1._year == d2._year
		&& d1._month == d2._month
		&& d1.day == d2.day;
}

这里会有一个小问题:
0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构
造成此问题的原因是:
Date类的这3个成员变量是私有的(private),所以在类外面是不能访问的。
那怎么解决?
我们可以在类里写一个Get方法(函数),通过Get方法来访问,或者直接把private访问限定符去掉。
我们这里先把private注释下:
0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构

现在我们来调用一下:

0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构
注意:因为这里<<的优先级比==高,所以要加括号。

但是这里直接重载到了全局,我们把成员变量全部公有了,封装性又如何体现呢?

所以这里比较好的一种方法是:我们直接重载到类里面,即重载成成员函数。

但是这里又出现了一个小问题如果直接把函数封装在类里:

0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构
这里我们重载的是==运算符,正常情况下只有两个操作数,所以只需要两个参数就够了。
那这里不就是两个参数嘛?
不要忘了,这里还有一个隐藏参数。什么隐藏参数,就是this指针。
C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象)
所以我们这里只需给一个参数。

bool operator==(const Date& d)
	{
		return _year == d._year
			&& _month == d._month
			&& _day == d._day;
	}

注意:

  1. 不能连接其他符号来创建新的操作符:比如operator@
  2. 重载操作符至少有一个类类型的参数
  3. 用于内置类型的运算符,其含义不能重载改变,例如:内置的整型+,不能改变其含义
  4. 作为类成员函数重载时,其形参看起来比操作数数目少1个,因为成员函数的第一个参数为隐藏的this
  5. .* :: sizeof ?: .注意这5个运算符不能重载,这个经常在笔试选择题中出现。
5.2赋值重载

参数类型:const 类对象的引用,传递引用可以提高传参效率
返回值类型:类类型&,返回引用可以提高返回的效率,有返回值目的是为了支持连续赋值
最好检测一下是否是自己给自己赋值,并进行一下处理
返回*this:返回的结果用于支持连续赋值

那么日期类的赋值重载就是:

	Date& operator=(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
		return *this;
	}

但是有时候呢不排除有人可能会把自己赋值给自己,于是它调用函数白白进行了一次拷贝,我们对此进行改进

	Date& operator=(const Date& d)
	{
		if (this != &d)
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}
		return *this;
	}


5.3赋值运算符重载特性
  1. 用户没有显式实现时,编译器会生成一个默认赋值运算符重载,以值的方式逐字节拷贝(浅拷贝)。

注意:默认生成的赋值重载对于内置类型成员变量是直接赋值的,而自定义类型成员变量需要调用其对应类的赋值运算符重载完成赋值。

那么下面这种情况会调用拷贝构造还是赋值重载?

0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构
这里用了赋值=,但是是拷贝构造。
什么时候是调赋值重载呢?
是我们用已经实例化出来的对象进行相互赋值的时候,调用赋值重载。而当我们用一个已经实例化出来的对象去初始化一个新对象的时候,调的是拷贝构造。

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

原因:赋值重载如果在类里不显式实现,编译器会生成一个默认的。此时用户再在类外自己实现一个全局的赋值运算符重载,就和编译器在类中生成的默认赋值运算符重载冲突了,故赋值运算符重载只能是类的成员函数。
0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构

6.const成员

将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,实际修饰该成员函数 隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。

以刚才的赋值重载函数为例:

Date& operator=(const Date& d) const
	{
		if (this != &d)
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}
		return *this;
	}

0基础入门C++之类和对象中篇,C++,c++,c语言,数据结构

7.取地址及const取地址操作符重载

这两个默认成员函数一般不用重新定义 ,编译器默认会生成。

这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需要重载,比如想让别人获取到指定的内容!文章来源地址https://www.toymoban.com/news/detail-660796.html

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

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

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

相关文章

  • C++从入门到精通——类和对象(中篇)

    如果一个类中什么成员都没有,简称为空类。空类中什么都没有吗?并不是的,任何一个类在我们不写的情况下,都会自动生成下面6个默认成员函数。 对于以下的日期类: 运行结果: 对于Date类,可以通过SetDate公有的方法给对象设置内容,但是如果每次创建对象都调用该方

    2024年04月12日
    浏览(35)
  • C++语言程序设计之类和对象进阶(3)

            这一部分介绍C++友元函数、友元类和this指针。         友元函数,可以在类的成员函数外部直接访问对象的私有成员。 1.1.1 设计代码 1.1.2 执行结果 图1 友元函数代码执行结果

    2024年01月25日
    浏览(42)
  • 数据结构零基础入门篇(C语言实现)

    前言:数据结构属于C++学习中较难的一部分,对应学习者的要求较高,如基础不扎实,建议着重学习C语言中的指针和结构体,万丈高楼平地起。 目录:   一,链表 1)单链表的大致结构实现 2)单链表的思考(然后找到链表和判断链表的结束) 3)单链表的程序实现及源代码

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

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

    2024年02月15日
    浏览(50)
  • 【C++笔记】C++之类与对象(上)

    C++的一个显著特征就是兼容C语言,所以C++把结构体“升级”成了“类”,之所以是“升级”是因为,在C++中的结构体及支持以前C语言的结构体的玩法,也可以支持C++中类的玩法。 例如单链表节点这个类,我们既可以写成纯C版本: 用纯C的写法,我们每次要定义一个节点变量

    2024年02月12日
    浏览(38)
  • 【C++初阶】之类和对象(中)

    📃 博客主页: 小镇敲码人 💞 热门专栏:C++初阶 🚀 欢迎关注:👍点赞 👂🏽留言 😍收藏 🌏 任尔江湖满血骨,我自踏雪寻梅香。 万千浮云遮碧月,独傲天下百坚强。 男儿应有龙腾志,盖世一意转洪荒。 莫使此生无痕度,终归人间一捧黄。🍎🍎🍎 ❤️ 什么?你问我

    2024年04月13日
    浏览(47)
  • 【C++初阶】之类和对象(下)

    📃 博客主页: 小镇敲码人 💞 热门专栏:C++初阶 🚀 欢迎关注:👍点赞 👂🏽留言 😍收藏 🌏 任尔江湖满血骨,我自踏雪寻梅香。 万千浮云遮碧月,独傲天下百坚强。 男儿应有龙腾志,盖世一意转洪荒。 莫使此生无痕度,终归人间一捧黄。🍎🍎🍎 ❤️ 什么?你问我

    2024年04月16日
    浏览(83)
  • c++学习之类与对象3

    目录 成员变量和函数的存储 this指针 this指针的工作原理 this指针的应用 const修饰的成员函数 友元 友元的语法 1.普通全局函数成为类的友元 2.类的某个成员函数作为另一个类的友元 整个类作为另一个类的友元 运算符重载 1 运算符重载的基本概念 2 重载加号运算符 3 重载左移

    2023年04月21日
    浏览(42)
  • C++初阶之类和对象(中)

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

    2024年02月12日
    浏览(30)
  • C++初阶之类和对象(下)

    在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。 虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化, 构造函数体中的语句只能将其称为赋初值 ,而不能称作初始化。因为 初始化只能

    2024年02月13日
    浏览(30)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包