C++ const
来源:互联网 发布:丹尼斯·约翰逊数据 编辑:程序博客网 时间:2024/04/27 23:39
目的: 值代替。
预处理宏定义的缺点: 只做文本替换,并没有类型检查,这样会产生风险。内存存储形式,常量折叠
常量的定义会保存在符号表中,可折叠的常量像宏一样,在预编译阶段对常量的引用一律被替换为常量所对应的值。但在运行时常量也是会被分配内存空间的。下面的程序可以说明。
int main() { const int i=0; int *j = (int *) &i; *j=1; printf(" addr_i=%d\n addr_j=%d\n val_i=%d\n val_j=%d\n",&i,j,i,*j); return 0; }
运行时指针j是可以取得常量i的地址,但无法修改地址中的值,原因是预编译时常量i已经通过常量折叠进行了替换,
在运行时用到i的地方已经替换为0,但i在内存中还是被分配了空间的。
使用形式:
1) 普通常量
const int ArrSize=10;int arr[ArrSize];
2) 常量集合
常量也可以用于集合,但集合无法被放入符号表中,必须分配内存。此时常量的含义是 "不能改变的一块存储"。// 正确
const int SizeArr[] = {1,2,3,4};
// 下面的使用方法是错误的
float farr[SizeArr[2]]; //错误
原因: 常量集合SizeArr无法被保存到符号表中,所以预编译时无法对SizeArr[2]进行替换。
从编译时提示的错误信息也可以看的很清楚
error C2057: expected constant expression
error C2466: cannot allocate an array of constant size 0
error C2133: 'farr' : unknown size
3) 指针
指向const指针 const int* x; int const* x;一个指针,指向一个const 变量, 不需要初始化,可以指向不同的常量。 地址可变::值不可变
const int i=10; const int j = 100; const int* x; x = &i;cout << *x << endl; x = &j;cout << *x << endl;*x = 5; // 错误 error C3892: 'x' : you cannot assign to a variable that is const
const 指针 int* const x;
指针本身为const指针,指针指向的地址不能改变,必须初始化。 地址不可变::值可变
int i = 5;int* const x = &i; *x = 15;cout << *x << endl; // output : 15 i = 25;cout << *x << endl; // output : 25
4) 函数参数和返回值
const 参数: void fun1(const int i)void fun1(const int i)
{
i++; // 错误 error C3892: 'i' : you cannot assign to a variable that is const
}
当以穿值方式向函数中传递参数时,会发生创建副本的情况,const也作为副本的一部分在函数中生效。
但把这个过程呈现出来更好些,效果是一样的。
void fun1(int i)
{
const int ic = i;
}
但函数接口如果是传引用或指针,如果不希望被修改最好还是用const。
const 返回值:
const 如果用于简单类型的返回值,并没有太大意义。 例如:
const int fun2()
{
return 0;
}
用于用户自定义类型的比较有意义的。 例如:
class X { int _i = 0;public: X(int i):_i(i){}; void modify(){_i++;}};X func3(){return X();}const X func4(){return X();}void func5(X &x){x.modify();}void main(){ func3() = X(1); func3().modify(); func5(func3()); func4() = X(1); // 错误 func4().modify(); // 错误 func5(func4()); // 错误}
这里对于返回对象为const的是无法进行修改的,在实际应用中是有意义的。
如果传递的参数为指针或地址,如果不希望参数在函数执行过程中被改变,尽可能的用const进行修饰。
类中的const类型
错误的使用
class A { private: const int _size=100; // 非 static 的 const型无法在类中被初始化 int _arr[_size]; // 所以此处也无法确定数组的大小 public: A(){}; };
正确的使用
class A { private: const int _size; int *_arr; public: A() : _size(100){_arr = new int[_size]}; }; class A { private: enum {_size=100}; int _arr[_size]; public: A(){}; };
const 对象和成员函数
有个对象,如果被定义为const,在应用的过程中,它的行为应该是怎样的?怎样保证 const 对象在调用它自身的成员函数时保证对象不会被改变?
例如一个类 B
class B { private: int _i; public: B(int i): _i(i) {}; void add(); int const_add() const; // const 成员函数 void show() const; // const 成员函数 }; void B::add() { _i++; } void B::show() const { cout << _i << endl; } int B::const_add() const { //_i++; // 错误: 在const 成员函数中尝试改变对象的成员变量 return _i; } int main() { B b(2); const B cb(4); b.add(); b.const_add(); b.show(); cb.add(); // 错误: cb 为 const 类型,不能通过cb的成员函数修改cb。 cb.const_add(); cb.show(); return 0; }
如何修改const 对象中的成员变量,使用关键字 mutable
class Y { int _i; mutable int _j; public: Y(){}; void addi() const; void addj() const; }; void Y::addi() {_i++;} // 错误: 通过const 成员函数修改成员变量 void Y::addj() {_j++;} // 正确: _j 为mutable类型,可以跳过 const 限制 int main() { const Y cy; cy.addi(); cy.addj(); return 0; }
0 0
- const c
- const【C++】
- const ||c
- C++Const
- [c++]const
- C++:const
- const用法(C/C++)
- C++/C const问题
- 【c/c++】const引用
- readonly vs. const [C#]
- C++(二)const
- C语言const介绍
- C语言const介绍
- readonly vs. const [C#]
- readonly vs. const [C#]
- c++:const 操作小结
- readonly vs. const [C#]
- C中的CONST
- Servlet中HttpSession源码
- win7技巧:win7开机启动项怎么设置
- [人工智能][转]机器学习之迭代法
- nginx简单应用—通过有外网全向的主机访问内网程序
- eclipse内部启动tomcat,报内存太小或内存溢出问题解决
- C++ const
- Ajax工作原理
- java wait()和sleep()的区别
- MFC界面库
- C#中操作Excel(5)—— 操作Excel的两种技术(一)--COM技术
- jquery事件代理方法
- 印制线路板的制造原理简介
- 自己的shell
- window开机 关机 记录日志