0
点赞
收藏
分享

微信扫一扫

C++类与对象(补)

冬冬_79d4 2024-08-19 阅读 36

文章目录

  • 前言
  • 一.默认成员函数
  • 二.static
  • 三.友元
  • 四.匿名对象
  • 总结


前言

类的默认成员函数,默认成员函数就是用户没有显式实现,编译器会自动生成的成员函数称为默认成员函数。一个类,我 们不写的情况下编译器会默认生成以下6个默认成员函数。


一.默认成员函数

1.1构造函数

因为前面对构造函数进行过了讲解,这里只做补充

对于编译器默认生成的构造,对内置类型成员变量初始化没有要求,但对于自定义类型成员变量,会调用这个成员变量的默认构造函数,如果这个成员变量没有构造函数就会报错,这时候就用初始化成员列表。

那么什么是内置类型和自定类型呢?C++把类型分为两类,内置类型和自定义类型,内置类型就是int,char,float,指针这种,自定义类型就是类,结构体,class,struct

这句话不是很好理解,我们来举个例子,方便理解一下

例子:

#include<iostream>
using namespace std;
class Date
{
public:
	
	Date()
	{
		_year = 1;
		_month = 1;
		_day = 1;
	}

	Date(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(2025, 1, 1); 
	Date d3();
	return 0;
}

class MyQueue
{
public:
	private:
	Stack pushst;
	Stack popst;
};

编译器默认生成MyQueue的构造函数调用了Stack的构造,完成了两个成员的初始化

1.2析构函数

1.3拷贝构造函数

C++语法规定,传值传参会掉用拷贝构造函数。

我们之前讲过引用的本质是常量指针,所以说,如果不是引用的话,他就会无限递归

这个地方和前面的有所差距,比如说我们再用那个站来实现队列的例子,这个地方就不能用系统自己的拷贝构造了

int main()
{
	Stack st1;
	st1.Push(1);
	st1.Push(2);
	// Stack不显示实现拷贝构造,用自动生成的拷贝构造完成浅拷贝
	// 会导致st1和st2里面的_a指针指向同⼀块资源,析构时会析构两次,程序崩溃
	Stack st2 = st1;
	MyQueue mq1;
	// MyQueue自动生成的拷贝构造,会自动调用Stack拷贝构造完成pushst/popst
	// 的拷贝,只要Stack拷贝构造自己实现了深拷贝,他就没问题
	MyQueue mq2 = mq1;
	return 0;
}

这里我们在前面的类与对象中讲了浅拷贝和深拷贝的问题,在这个地方就不多做解释了。

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

1.4赋值运算符重载

int main()
{
	Date d1(2024, 7, 5);
	Date d2(2024, 7, 6);
	//赋值重载拷贝
	operator==(d1, d2);
	d1 == d2;
	//拷贝构造
	Date d3(d2);
	Date d4 = d2;
	return 0;
}

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

这个地方不做过多的讲解,到时候会专门来出一个日期类的实现,就专门运用这个赋值运算符重载来实现的。

1.5取地址运算符重载

class Date
{

public:
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	// void Print(const Date* const this) const
	void Print() const
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	//这里非const也可以调用const成员函数这是⼀种权限的缩⼩
	Date d1(2024, 7, 5);
	d1.Print();
	const Date d2(2024, 8, 5);
	d2.Print();
	return 0;
}

1.6*取地址运算符重载

class Date
{
public:
	Date* operator&()
	{
		return this;
		// return nullptr;
	}
		const Date * operator&()const
	{
		return this;
		// return nullptr;
	}
private:
	int _year;
	int _month; 
	int _day; 
};

二.static

class A
{

static int GetACount()
{
	return _scount;
}
private:
	// 类⾥⾯声明
	static int _scount;
};
// 类外⾯初始化
int A::_scount = 0;
int main()
{

	return 0;

}

例子:求1+2+3+...+n_牛客题霸_牛客网 (nowcoder.com)

class Sum
{
public:
Sum()
{
_ret += _i;
++_i;
}
static int GetRet()
{
return _ret;
}
private:
static int _i;
static int _ret;
};
int Sum::_i = 1;
int Sum::_ret = 0;
class Solution {
public:
int Sum_Solution(int n) {
// 变⻓数组
Sum arr[n];
return Sum::GetRet();
}
};

有static成员变量就肯定有static成员函数

#include<iostream>
using namespace std;
class A
{
public:

	static int GetACount()
	{
		return _scount;
	}
private:
	
	static int _scount;
};
int A::_scount = 0;
int main()
{
	A a1;
	cout << A::GetACount() << endl;
	cout << a1.GetACount() << endl;
	return 0;
}

三.友元

class A
{
	// 友元声明
	friend void func(const A& aa);
private:
	int _a1 = 1;
};

void func(const A& aa)
{
	cout << aa._a1 << endl;
}
int main()
{
	A aa;
	func(aa);
	return 0;
}
class A
{
	// 友元声明
	friend class B;
private:
	int _a1 = 1;
};
class B
{
public:
	void func1(const A& aa)
	{
		cout << aa._a1 << endl;
		cout << _b1 << endl;
	}
private:
	int _b1 = 3;
};
int main()
{
	A aa;
	B bb;
	bb.func1(aa);
	return 0;
}

内部类

class A
{
private:
	static int _k;
	int _h = 1;
public:
	class B // B默认就是A的友元
	{
	public:
	
			void foo(const A & a)
		{
			cout << _k << endl; 
			cout << a._h << endl; 
		}
	};
};
int A::_k = 1;

A是B的外步类,B默认就是A的友元,B是A的友元,B可以访问到A的私有,A不可以访问B的

四.匿名对象

class A
{
    private:
		int a = 2;
		int b = 1;
public:
	void print()
	{
		cout << print << endl;
	}
};
int main()
{
	A().print();

	return 0;
}

总结

这次是对之前的类与对象的一个补充,完善了一下类与对象的实现。

举报

相关推荐

0 条评论