C++:常量

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

const的最初动机

const的使用方法

使用const的好处是允许指定一种语义上的约束,即某种对象不能被修改,且由编译器具体实施这种约束。
const声明格式:const 类型名 对象名;修饰普通变量,时期不能被随意修改
【注意】1.C++中的const为内部连接,即由const定义的常量仅在被定义的文件中才能看见,除非使用extern。一般情况下,编译器不为const分配空间(而extern则强制分配空间)。
2. 当定义一个常量(const)时,必须进行初始化,即赋初值给它,除非已经用extern最清楚说明。
可以使用const修饰数组,表示“常”数组,即数组的值不能被修改。例如

const int data[] = { 1, 2, 3 };//合法使用,定义一个常量数组
struct MyStruct
{
   int i, j;
};
const MyStruct mList[] = { {1, 2}, {3, 4} };//定义一个结构体常量数组
data[0] = 10;  //错误
mList[1].i = 4;//错误

同时,定义上述数组后,对常数组的一下引用也是错误的。

char cList[data[2]];//错误
float fList[mList[0].i];//错误

错误原因在于,在编译时编译器必须为数组分配固定大小的内存。而用const修饰的数组意味着“不能被改变”的一块存储区,但其值在编译期间不能被使用。

const与指针

const与指针的结合使用由两种情况:1.用const修饰指针,即修饰存储在指针里的地址;2.修饰指针指向的对象。
为了防止使用混乱,采用“就近原则”,即const距离哪个近就修饰哪个:若const距离变量近,则表示的含义为指向常量的指针;若const距离指针近,则表达的含义为指向变量的常指针。

指向常量的指针

定义格式:const 类型名* 指针变量名;或者类型名 const* 指针变量名;这两种格式是等价的。

const int data = 10;
const int *p = &a;
*p = 20; //错误
const int max = 20;
p = &max; //正确

表明p是一个指向const int的指针。指针所指向的单元不能修改,但是其本身为指针变量可以指向别的位置。

常指针

定义格式为:类型名 *const 指针名;

int i = 1;
int * const p = &i;

表明p是一个常指针,一个指向int类型的变量i的const指针,p必须用一个初值,它只能指向这个初始对象i,不能“被改变”而指向其他对象,但对象的值可以被修改。
同时,不仅可以使用一个常指针指向一个变量,也可以把非const对象变成const对象。例如:

int a = 10;
int *const p = &a;      //可以用const指针指向一个非const对象
const int *const q = &a;//可以把const对象地址赋值给const对象指针

const与函数

函数与const的结合使用由两种方式:1.参数为const类型;2.返回值为const类型。

const类型的参数

定义格式:返回值类型 函数名称(const 类型 参数名,···)例如:

void f(const int  i){
	i++;//错误
}

当c++在函数的参数使用引用时,需要特别注意对常量引用的使用。例如:

void f1(int&) {}
void f2(const int&) {}
int main() {
	f1(1);//错误,在f1()中,可以修改参数内容,而1为常量
	f2(1);//正确,在f2()中,参数声明为常量
	int n = 10;
	const int m = 11;
	f1(n);//正确
	f1(m);//错误,不能使用普通引用方式引用常量
	f2(n);//正确,可以用常量方式引用普通常量
	f2(m);//正确
	return 0;
}

const类型的返回值

可以用const修饰函数的返回值,即函数返回一个常量值,此常量值即可以赋给常量(对常量初始化),也可以赋给变量。其对返回值为某个类对象时,会显得尤为重要。
常对象的使用:

class MyClass
{
public:
	MyClass(int i = 0):data(i){}
	void seti(int i) {
		data = i;
	}
private:
	int data;
};
MyClass test1() {
	return MyClass();//返回为普通对象
}
const MyClass test2() {
	return MyClass();//返回为常对象
}
int main() {
	test1() = MyClass(10);//正确,test1()返回一个MyClass对象,并把对象MyClass(10)的值赋给它
	test1().seti(20);//正确,调用test1(),得到一个返回对象,并调用此对象的成员函数seti()
	test2() = MyClass(10);//错误,常对象不能被修改(赋值)
	test2().seti(20);//错误,常对象不能被修改
	return 0;
}

const与类

const在类里有两种应用:1.是在类里建立类内局部常量,可用在常量表达式中,而常量表达式在编译期间被求职;2.是const和类成员函数的结合使用。

类内const局部常量

在一个类内使用const修饰的意思就是“在这个对象的寿命期内,这是一个常量。”然而,对这个常量来讲,每个不同的对象可以含有一个不同的值。
在类内建立一个const成员时不能赋初值,只能在构造函数里面对其赋初值,而且要放在构造函数的特殊地方,因为const必须在创建它的地方被初始化,所以在构造函数的主体里,const成员必须已被初始化。例如:

class MyClass
{
public:
	MyClass():num(100){}
private:
	const int num;
};

常用的一种情况就是,在类内声明一个常量,用这个常量来定义数组的大小,把数组的大小隐藏在类内。
错误示范:

class MyClass
{
public:
	MyClass();
private:
	const int num = 100;//错误
	int data[100];//错误
};

因为在类内进行存储空间分配时,编译器无法知道const的内容是什么,所以不能把它用于编译期间的常量。
解决这种问题的方法有两种:

  1. 静态常量。为提高效率保证所有的类对象最多只有一份拷贝值,通常需要将常量声明为是静态的。例如:
class MyClass{
	static const int num = 100;
	int mList[num];
};
  1. enum(枚举常量)。例如:
class MyClass{
	enum{num = 100};
	int data[num];
};

常对象与常成员函数

声明一个“复杂”的对象为常量,对于公有数据这点很容易做到,然而对于私有数据,该如何保证每个成员函数的调用不改变呢?需要声明这个成员函数为const类型,等同于告诉编译器此类的一个const对象可以调用这个成员函数,而const对象调用非const成员函数。
const成员函数定义格式:class 类名{返回值类型 成员函数名称(参数列表) const;};
【注意】若在函数的前面加上const,则表明函数返回值为const,为防止混乱,应把const放在函数的后面。在一个const成员函数里,试图改变任何数据成员或调用非const成员函数,编译器都将显示出错误信息。
例如:const成员函数与非const成员函数使用方式的比较。

//student.h
#ifndef STUDENT_H_//防止重复包含头文件student.h
#define STUDENT_H_
class Student{
	int No;
	char Name[20];
public:
	Student();
	int GetNo() const;//const成员函数
	const char* GetName();//返回值为const的成员函数,不是const成员函数
};
#endif
//student.cpp
#include <string.h>
#include <student.h>
Student::Student(){
	No = 1;
	strcpy(Name, "wang");
}
int Student::GetNo()const{
	return No;
}
const char* Student::GetName(){
	return Name;
}
//test.cpp
#include <student.h>
int main(){
	Student s1;
	s1.GetNo();
	s1.GetName();
	const Student s2;
	s2.GetNo();//正确,常对象调用const成员函数
	s2.GetName();//错误,常对象调用了非const成员函数
	return 0;	

然而,有时候我们需要修改对象的某些数据成员时该怎么办?有两种方法.
1.强制转换。在常成员函数中修改成员变量的值。文章来源地址https://www.toymoban.com/news/detail-780939.html

class Test{
	int i, j;
public:
	Test():i(0),j(0){};
	void f()const;
};
void Test f()const{
	i = 1; //错误,在常成员函数中修改类成员
	((Test*)this)->j = 5; //正确
}
int main(){
	const Test t;
	t.f();//正确
	return 0;
}
  1. 使用mutable,用它指定某个特定的数据成员在常量对象的某个函数里是可以被修改的。在常成员函数中修改有mutable所修改的变量值。
class Test{
	int i;
	mutable int j;
public:
	Test():i(0),j(0){};
	void f()const;
};
void Test f()const{
	i = 1; //错误,在常成员函数中修改类成员
	j = 5; //正确,可以在常成员函数中修改被mutable修饰的类成员
}
int main(){
	const Test t;
	t.f();//正确
	return 0;
}

到了这里,关于C++:常量的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【C++学习笔记】7、常量

    常量 是固定值,在程序执行期间不会改变。这些固定的值,又叫做字面量。 常量可以是任何的基本数据类型,可分为整型数字、浮点数字、字符、字符串和布尔值。 常量和变量的关系 :常量就像是常规的变量,只不过常量的值在定义后不能进行修改。 整数常量可以是十进

    2024年02月10日
    浏览(23)
  • 【C++】C 语言 和 C++ 语言中 const 关键字分析 ( const 关键字左数右指原则 | C 语言中常量的原理和缺陷 | C++ 语言中常量原理 - 符号表存储常量 )

    【C 语言】const 用法 ( 常量指针 - const 在 * 左边 - 修饰数据类型 - 内存不变 | 指针常量 - const 在 * 右边 - 修饰变量 - 指针不变 ) 普通类型数据的常量定义时 , const 在 数据类型 的 左边 和 右边 其作用 是相同的 ; 指针数据的相关常量类型 : const 在 指针符号

    2024年02月11日
    浏览(38)
  • 【C++】【命名规范】你的代码风格是哪种?(驼峰命名法、下划线命名法、帕斯卡命名法、常量命名法等)

            在 C/C++ 中,类名、接口名、变量名和函数名等的命名规则是比较自由的,开发者可以根据自己的喜好选择合适的命名方式。但是,为了保持代码的可读性和可维护性,我们通常遵守一些命名规则。         例如驼峰命名法、下划线命名法、帕斯卡命名法、常量

    2024年02月07日
    浏览(34)
  • jvm 什么是常量池,常量池定义 class常量池

    首先需要理解下Java的class文件,以及class文件结构: 1. Class文件 是一组以8个字节为基础单位的 二进制流 ,各个数据项目严格按照顺序紧凑地排列在文 件之中, 中间没有任何分隔符 ,这使得整个Class文件中存储的内容几乎全部是程序运行的必要数据, 没有空隙存在 。当遇到

    2024年02月11日
    浏览(34)
  • 【C/C++】 常量指针,指针常量、指向常量的常指针详解

    指针就是指向变量在内存中的地址 数据是存放在内存中的,每一个变量都有一个内存地址,假设是一个int类型变量 a ,占4个字节的内存区,那么在内存中如果是小端方式存储,我们创建指针p,把a的地址赋值给 p ,就是把a的首地址0x1100赋值给指针 p ,这个时候p的值就是变量

    2024年02月13日
    浏览(32)
  • Java面向对象核心修饰符,final修饰符、常量、常量方法与常量类

    之前跟大家说过,在面向对象中,有abstract、static和final 这3个核心修饰符。截止到现在,我们已经把abstract与static修饰符学习完毕,接下来就让我们再来学习final修饰符的用法与特性吧。 全文大约 【3500】字 ,不说废话,只讲可以让你学到技术、明白原理的纯干货!本文带有

    2024年02月04日
    浏览(33)
  • 【C语言趣味教程】(5) 常量:字面常量 | 类型常量 | const 关键字 | const 的声明 | 程序中的只读概念 | const 保护机制 | 如何巧妙区分 “指针常量“ 和 “常量指针“

        🔗 《C语言趣味教程》👈 猛戳订阅!!! ✨ 专栏介绍 / 总目录: 【C语言趣味教程】(0) 导航篇 ​ —— 热门专栏《维生素C语言》的重制版 —— 💭 写在前面: 这是一套 C 语言趣味教学专栏,目前正在火热连载中,欢迎猛戳订阅!本专栏保证篇篇精品,继续保持本人

    2024年02月15日
    浏览(35)
  • 什么是常量?如何区分常量和变量?

            什么是常量,什么是变量?怎样区分⼆者? 1. 常量与变量         (1)常量即其值在程序运⾏的过程中是不可以改变的,如123,-4567 为数值常量;         (2)变量是在程序运⾏期间其值是可以进⾏变化的量                  如 int a; char b:是整型变

    2024年02月02日
    浏览(33)
  • 指针变量、指针常量与常量指针的区别

    定义 :指针变量是指存放地址的变量,其值是地址。 一般格式 :基类型 指针变量名;(int p) 关键点 : 1、int * 表示一种指针类型(此处指int 类型),p(变量名)即为定义的指针变量名。 2、在定义指针变量时必须指定基本类型,知道数据类型,才能按存储单元的长度以及数据的

    2024年02月11日
    浏览(38)
  • c语言中指针常量和常量指针

    指针常量(Pointer to Constant)和常量指针(Constant Pointer)是C和C++中用于描述指针和常量的组合概念。 指针常量本质是一个常量,它的值不能改变,即指针始终指向同一个地址。但通过指针可以修改所指向对象的值。 int* const ptr;//表示ptr是一个指针常量,指向一个整型常量对

    2024年02月10日
    浏览(27)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包