C++类学习笔记(4)

类的成员函数

 

class Date
{
public:
	//构造函数的重载
	Date()
	{
 
	}
	Date(int year,int month,int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1;//创建并通过无参构造函数初始化对象时,无需加括号,不然变成了函数声明
	Date d2(2022,9,23);
	return 0;
}

 

 

 

 

class Stack
{
public:
	Stack(int capacity=100)//构造函数
	{
		_capacity = capacity;
		_top = 0;
		_arr = (int*)malloc(sizeof(int) * 5);
		if (_arr == nullptr)
		{
			perror("malloc fail");
			exit(-1);
		}
	}
	//Stack(const Stack& st)//浅拷贝,栈这个类不能用浅拷贝
	//{
	//	_capacity = st._capacity;
	//	_top = st._top;
	//	_arr = st._arr;
	//}
	Stack(const Stack& st)//深拷贝
	{
		_capacity = st._capacity;
		_top = st._top;
		_arr = (int*)malloc(sizeof(int) * st._top);
		if (_arr == nullptr)
		{
			perror("malloc fail");
			exit(-1);
		}
		memcpy(_arr, st._arr,sizeof(int)*st._top);
	}
	~Stack()//析构函数
	{
		_capacity = 0;
		_top = 0;
		free(_arr);
		_arr = nullptr;
	}
private:
	int* _arr;
	int _top;
	int _capacity;
};

 栈这个类因为成员变量中有动态开辟的空间,所以要用深拷贝。

( 补充:C++ const的用法详解)

一 const的基本概念

const名叫常量限定符,用来限定特定变量,以通知编译器该变量是不可修改的。习惯性的使用const,可以避免在函数中对某些不应修改的变量造成可能的改动。

二 const修饰基本数据类型

2.1 const修饰一般常量及数组

int const a = 100;
const int a = 100; //与上面等价
int const arr [3] = {1,2,3};
const int arr [3] = {1,2,3};//与上面等价

对于这些基本的数据类型,修饰符const可以用在类型说明符前,也可以用在类型说明符后,其结果是一样的。

2.2 const修饰指针(*)

主要有以下几种类型:

char *p = "hello";     // 非const指针,
                       // 非const数据

const char *p = "hello";  // 非const指针,
                          // const数据

char * const p = "hello";   // const指针,
                            // 非const数据

const char * const p = "hello";  // const指针,
                                 // const数据

2.2.1 常量指针

当为常量指针时,不可以通过修改所指向的变量的值,但是指针可以指向别的变量。

int a = 5;
const int *p =&a;
*p = 20;   //error  不可以通过修改所指向的变量的值

int b =20;
p = &b; //right  指针可以指向别的变量
2.2.2 指向常量的指针(指针常量)

当为指针常量时,指针常量的值不可以修改,就是不能指向别的变量,但是可以通过指针修改它所指向的变量的值。

int a = 5;
int *const p = &a;
*p = 20;     //right 可以修改所指向变量的值

int b = 10;
p = &b;      //error 不可以指向别的变量
2.2.3 总结

如果const位于星号*的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;

如果const位于星号*的右侧,const就是修饰指针本身,即指针本身是常量。

通俗理解:
左定值,右定向,const修饰不变量

2.2.4具体举例

代码如下:

int main()
{
	int a = 10, b = 20;

	int* p1 = &a;    //可以修改值 也可以修改方向
	*p1 = 100;
	p1 = &b;

	const int* p2 = &a;   //指向
	//int x2=*p2;
	//*P2=100;//error
	//p2=&b;
	int const* p3 = &a;
	//const 在指针前 修饰指向方向可以读取值 自身值可以改变
	int* const p4 = &a;
	//int x=*p4;
	// *p4=100;
	//p4=&b;//error
	//const 在指针后 修饰值本身 p4的值不可以改变 但是后面修饰的值可以
	const int* const p5 = &a;//指针前有指针后也有 均不可以改变
	return 0;

 

三 const修饰函数

const 在函数中根据修饰的位置分为三种:函数参数、函数返回值、成员函数。

const  int fun (const int a) const;

3.1 const修饰函数参数

修饰函数形参;函数体内不能修改形参a的值。

如果函数作为输出用,不论是什么数据类型,也不论采用指针传递还是引用传递,都不能加const 修饰,否则参数会失去输出功能。

所以:const 只能修饰输入作用的参数

3.1.1 如果参数为指针

如果输入参数为指针,加上const之后就会起保护指针意外修改的作用。

void StringCopy(char* strDest, const char* strSource);

在这个函数定义中,我们的的参数strsource加上const修饰,就是为了防止strsource被修改。

可以起到保护作用的原因是:
实参中,指针会指向一段内存地址,调用函数之后,函数会产生一个临时指针变量,这个变量的地址与实参的地址不一样,但是这两个指针指向的内存是同一块。形参加上const 修饰之后,保护了这一块内存地址不被修改,如果刻意修改这一块内存,编译器会报错。

3.1.2 如果参数为引用

如果输入参数为引用,加上const 之后既起到了保护作用,也提高了程序效率。

这里关于引用的知识点我们不详细介绍,可以参考这篇blog链接: 引用详解

void func(Y y);//这里的Y类型为用户定义的类型
void func(Y &y);//采用引用的方式

调用这个函数我们会产生一个临时对象,随后调用拷贝构造函数,当函数结束的时候,进行析构释放资源。

如果改成引用void func(A &a); 只是相当于实参的一个别名,不会产生临时变量。

所以,如果是自定义类型,建议用引用作为函数形参。

3.2.2 返回值为指针

如果返回值为指针,加上const修饰后,同样的内容是不可以修改的。

这个时候我们接收的变量也必须是const修饰:

const char* func();
char* str = func();// error 
const char* str = func(); //right
3.2.3 返回值为引用

如果返回值为引用,也可以提高效率。但是一般返回引用的地方并不是很多,一般会出现在类的赋值函数中。而且,用const 修饰返回值为引用类型的更少。一般来说不常用。

3.3 const修饰成员函数

const 修饰的成员函数为了保护成员变量,要求const 函数不能修改成员变量,否则编译会报错。
函数体内不能修改成员变量的值,增加程序的健壮性或鲁棒性。只有成员函数才可以在后面加const,普通函数后加const无意义。

class MyClass {
public:
    void func(int x) const;
};

const函数的规则
const 对象只能访问const 成员函数,非const 的对象可以访问任何成员函数,包括const 成员函数。
如果函数名、参数、返回值都相同的const成员函数和非const成员函数是可以构成重载,那么const对象调用const成员函数,非const对象默认调用非const的成员函数。
const成员函数可以访问所有成员变量,但是只能访问const的成员函数。
非const成员函数,可以访问任何成员,包括const成员成员函数。
const成员函数不能修改任何的成员变量,除非变量用mutable修饰。

 

 

                        
学习链接:https://blog.csdn.net/weixin_56935264/article/details/125760242

  • 19
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值