[C++]const成员 - 详解

目录

观看建议:看这边文章前可以先复习该篇博客内容,可以更好理解本篇博客内容。[C语言]const 修饰 指针(看一遍就能懂)

一、const成员变量

1、为什么const成员变量必须在构造函数的初始化列表中初始化,而不能在构造函数体内赋值。

2 、const成员变量初始化时间线

3、const成员变量初始化编译器视角理解

二、const成员函数

1、普通对象调用非const成员函数

2、普通对象调用const成员函数

3、const对象不可以调用非const成员函数

4、const对象可以调用const成员函数

5、const成员函数不能调用非const成员函数

6、非const成员函数可以调用const成员函数

三、总结

1、const成员变量

2、const成员函数

观看建议:看这边文章前可以先复习该篇博客内容,可以更好理解本篇博客内容。[C语言]const 修饰 指针(看一遍就能懂)

一、const成员变量

在 C++ 中,const 成员主要分为两类:const 成员变量const 成员函数。它们共同保证了对象的某些部分在生命周期内不可被修改。

  • 在类中声明的成员变量前面加上const关键字,表示这个成员变量是一个常量。

  • const成员变量必须在构造函数的初始化列表中进行初始化,因为一旦初始化后,其值就不能再改变。

  • 注意:const成员变量不能使用赋值操作在构造函数体内初始化,必须使用初始化列表。

1、为什么const成员变量必须在构造函数的初始化列表中初始化,而不能在构造函数体内赋值。

const成员变量的常量特性:const成员变量一旦被初始化,其值就不能再改变在对象的整个生命周期中,const成员变量只能被初始化一次。

 构造函数体中的操作属于赋值,而不是初始化。当程序执行到构造函数体时,对象的所有成员已经经过了默认初始化(除非使用了初始化列表)。对于const成员变量,此时如果不在初始化列表中初始化,那么它就已经被默认初始化了(而且由于是const,之后不能再赋值),这会导致编译错误。

初始化列表是成员变量初始化的地方,特别是对于const成员、引用成员以及没有默认构造函数的类类型成员,都必须使用初始化列表进行初始化。

2 、const成员变量初始化时间线

3、const成员变量初始化编译器视角理解

// 伪代码:编译器视角的对象构造过程
void Test_constructor(Test* this, int a, int b) {
    // 阶段1:成员初始化(初始化列表)
    this->x = ???;      // const成员必须在这里初始化
    this->y = ???;      // 非const成员也在这里初始化
    // 阶段2:构造函数体执行
    {
        // 这里只能进行赋值操作
        this->x = a;    // 错误:const变量不能重新赋值
        this->y = b;    // 正确:非const变量可以赋值
    }
}

二、const成员函数

  • 在成员函数的参数列表后面加上const关键字,表示这个成员函数不会修改类的任何成员变量(除了被声明为mutable的成员变量)。

  • const成员函数可以被const对象调用,也可以被非const对象调用。但是非const成员函数只能被非const对象调用。

  • 在const成员函数中,不能调用非const成员函数,因为非const成员函数可能会修改成员变量。

1、普通对象调用非const成员函数

class Date
{
public:
	//默认构造--全缺省构造
	Date(int year, int month, int day)
		:_year(year)
		,_month(month)
		,_day(day)
	{}
    //非const成员函数
	void Print()
	{
		cout << "void Print()" << endl;
		cout << "year=" << _year << " ";
		cout << "month=" << _month << " ";
		cout << "day=" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	//普通对象调用非const成员函数
	Date d1(2025, 11, 23);
	d1.Print();//权限平移 Date* const->Date* const
}
//输出结果
void Print()
year=2025 month=11 day=23

2、普通对象调用const成员函数

class Date
{
public:
	//默认构造--全缺省构造
	Date(int year, int month, int day)
		:_year(year)
		,_month(month)
		,_day(day)
	{}
    //const成员函数
	void Print() const
	{
		cout << "void Print() const" << endl;
		cout << "year=" << _year << " ";
		cout << "month=" << _month << " ";
		cout << "day=" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	//普通对象调用const成员函数
	Date d1(2025, 11, 23);
	d1.Print();//权限缩小 Date* const->const Date* const
}
//输出结果
void Print() const
year=2025 month=11 day=23

3、const对象不可以调用非const成员函数

class Date
{
public:
	//默认构造--全缺省构造
	Date(int year, int month, int day)
		:_year(year)
		,_month(month)
		,_day(day)
	{}
    //非const成员函数
	void Print()
	{
		cout << "void Print()" << endl;
		cout << "year=" << _year << " ";
		cout << "month=" << _month << " ";
		cout << "day=" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	//const对象不可以调用非const成员函数
	const Date d2(2025, 11, 24);//const对象d2
	d2.Print();//error  this指针不可以权限放大 即 const Date* const->Date* const
}

4、const对象可以调用const成员函数

class Date
{
public:
	//默认构造--全缺省构造
	Date(int year, int month, int day)
		:_year(year)
		,_month(month)
		,_day(day)
	{}
    //const成员函数
	void Print() const
	{
		cout << "void Print() const" << endl;
		cout << "year=" << _year << " ";
		cout << "month=" << _month << " ";
		cout << "day=" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	//const对象可以调用const成员函数
	const Date d3(2025, 11, 24);
	d3.Print();//this指针权限平移 即 const Date* const->const Date* const
}
//输出结果
void Print() const
year=2025 month=11 day=24

5、const成员函数不能调用非const成员函数

class Date
{
public:
	//默认构造--全缺省构造
	Date(int year, int month, int day)
		:_year(year)
		, _month(month)
		, _day(day)
	{}
	//非const成员函数
	void noConstFunc()
	{
		cout << "void noConstFunc()" << endl;
	}
	//const成员函数
	void ConstFunc() const
	{
		cout << "void ConstFunc() const" << endl;
	}
	void Print() const
	{
		cout << "void Print() const" << endl;
		cout << "year=" << _year << " ";
		cout << "month=" << _month << " ";
		cout << "day=" << _day << endl;
		//noConstFunc();//const成员函数不能调用非const成员函数
		ConstFunc();//const成员函数可以调用const成员函数
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	//const对象可以调用const成员函数
	const Date d3(2025, 11, 24);
	d3.Print();//this指针权限平移 即 const Date* const->const Date* const
}
//输出结果
void Print() const
year=2025 month=11 day=24
void ConstFunc() const

6、非const成员函数可以调用const成员函数

class Date
{
public:
	//默认构造--全缺省构造
	Date(int year, int month, int day)
		:_year(year)
		, _month(month)
		, _day(day)
	{}
	//非const成员函数
	void noConstFunc()
	{
		cout << "void noConstFunc()" << endl;
	}
	//const成员函数
	void ConstFunc() const
	{
		cout << "void ConstFunc() const" << endl;
	}
	//非const成员函数
	void Print()
	{
		cout << "void Print()" << endl;
		cout << "year=" << _year << " ";
		cout << "month=" << _month << " ";
		cout << "day=" << _day << endl;
		ConstFunc();//非const成员函数可以调用const成员函数 涉及权限缩小
                    //即 Date* const->const Date* const
		noConstFunc();//非const成员函数可以调用非const成员函数 涉及权限平移
                    //即 Date* const->Date* const
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
    //普通对象调用非const成员函数
	Date d1(2025, 11, 23);
	d1.Print();
}
//输出结果
void Print()
year=2025 month=11 day=23
void ConstFunc() const
void noConstFunc()

三、总结

1、const成员变量

const成员变量必须在构造函数的初始化列表中进行初始化,因为一旦初始化后,其值就不能再改变。

2、const成员函数

对于const成员函数,对于是否可以调用只需要观察this指针权限的情况,权限平移和权限缩小都可以,但是权限放大不行。

posted @ 2025-12-20 11:13  gccbuaa  阅读(0)  评论(0)    收藏  举报