Constants
- #define值替换
- 指针
-
- 指向常量的指针和常量指针
- 函数参数和返回值
-
- const参数传递
- 对于 const 修饰函数的返回值。
- 临时变量
- 类
-
- 常量数据成员
- 常量成员函数
- 常量对象
- mutable关键字
- volatile关键字
常量(用const关键字表示)的创建是为了让程序员在更改和不更改之间划清界限。这为c++项目提供了安全性和控制性。
//常量必须被初始化,但不能被赋值。
const int model=90; //model is a const
const int v[]={1,2,3,4}; //v[i] is a const
const int x; //error: no initilizer
…………
model=90; //error
v[2]++; //error
#define值替换
预处理程序#define只是进行文本替换,没有类型检查的概念和设施。
这种问题在c++中可以通过使用const值来避免。
#define BUFSIZE 100
const int bufsize = 100;
#define是一个宏
作用域从#define到#undef
BUFSIZE是一个替换
而const一份声明
Bufsize具有int类型
Bufsize默认为内部链接,作用域在整个文件。
指针
指向常量的指针和常量指针
char s[ ] = {'w','h','o'};
const char* pc = s; //pointer to a constant
pc[1]= 'i'; //error: pc points to a constant
pc="Hi"; //ok
char* const cp = s; //constant pointer
cp[1]= 'i'; //ok
cp = "Hi"; //error: cp is a constant
const char* const cpc=s; //constant
cpc[1]= 'i'; //error: cpc points to a constant
cpc = "Hi"; //error: cpc is a constant
常量的地址只能赋值给指向常量的指针。
const float f1=5.0;
float f2=0.0;
//float* p1=&f1; // error
//float* const p2=&f1; // error
const float* p3=&f1; // ok
float* p4=&f2; // ok
float* const p5=&f2; // ok
const float* p6=&f2; // ok
函数参数和返回值
void t(int* p) { }
void u(const int* cip)
{
*cip = 2; // Illegal
int i = *cip; // OK
}
const char* v( ) {……}
const int* const w( ) { ……}
void main( )
{
int x = 0;
int* ip = &x;
const int* cip = &x;
t(ip); // OK
t(cip); // error
u(ip); // OK
u(cip); // Also OK
char* cp = v(); // error
const char* ccp = v();
int* ip2 = w(); //error
const int* const ccip = w();
const int* cip2 = w(); // OK
*w() = 1; // error
}
const参数传递
值传递的 const 修饰传递,一般这种情况不需要 const 修饰,因为函数会自动产生临时变量复制实参值。
当 const 参数为指针时,可以防止指针被意外篡改。
自定义类型的参数传递,需要临时对象复制参数,对于临时对象的构造,需要调用构造函数,比较浪费时间,因此我们采取 const 外加引用传递的方法。
void Cmf(const Test& _tt)
{
cout<<_tt.get_cm();
}
对于 const 修饰函数的返回值。
const 修饰内置类型的返回值,修饰与不修饰返回值作用一样。
#include<iostream>
using namespace std;
const int Cmf()
{
return 1;
}
int Cpf()
{
return 0;
}
int main(void)
{
int _m = Cmf(); //_m=1
_m++; //_m=2
int _n = Cpf();
cout<<_m<<" "<<_n;
return 0;
}
const 修饰自定义类型的作为返回值,此时返回的值不能作为左值使用,既不能被赋值,也不能被修改。
const 修饰返回的指针或者引用,是否返回一个指向 const 的指针,取决于我们想让用户干什么。
临时变量
有时,在表达式求值期间,编译器必须创建临时对象(Temporaries)。
编译器将所有临时变量自动变为const。
#include <iostream>
using namespace std;
class Date
{
int year, month, day;
public:
Date()
{ year=month=day=0;
cout<<"Default constructor called."<<endl; }
Date(int y, int m, int d)
{ year=y; month=m; day=d;
cout<<"Constructor called."<<day<<endl; }
~Date( ) { cout<<"Destructor called."<<day<<endl; }
void Print( )
{cout<<year<<":"<< month<<":"<<day<<endl; }
};
void main()
{
//initialization
Date dates[3]={Date(2003,9,20),Date(2003,9,21)};
for (int i=0;i<3;i++)
dates[i].Print();
dates[2]=Date(2003,9,22); //assignment
for ( i=0;i<3;i++)
dates[i].Print();
}
类
常量数据成员
Const数据成员不能被修改。
Const数据成员必须在构造函数的成员初始化列表中初始化。
因为const和引用必须初始化,所以包含const或引用成员的类不能默认构造。
class A
{
public:
A(int i);
void Print();
private:
const int a; //const data member
static const int b; //static const
const int& r; //const reference
};
const int A::b=10;
A::A(int i):a(i),r(a) { …… }
常量成员函数
const成员函数不会修改数据成员。
定义方法:[type] [function-name] (arguments) const;
class Date
{
public:
Date(int i,int j, int k){y=i; j=m; d=k;}
int year() const;
int month() const { return m; }
int day() { return d;}
private:
int y, m, d ;
};
int Date::year() const //error: attempt to change member value
{
return y++;
}
int Date::year() const //correct
{
return y;
}
常量对象
const对象意味着在对象的生命周期内,该对象的任何数据成员都不会被更改。
void main()
{
Date A(2003,10,1); // non-const object
const Date B(2000,9,8); //const object
}
对于非const对象,const和非const成员函数都可以调用。
对于const对象,只能调用const成员函数。
mutable关键字
存储说明符mutable指定应该以允许更新的方式存储成员。
#include <iostream.h>
class Date {
public:
Date(int i,int j, int k){y=i; j=m; d=k;}
int day() { return ++d;}
int month() { return ++m; }
int year() const {return ++y; } // const member function
private:
mutable int y; // mutable data member
int m, d ;
};
void main() {
Date A(2003,10,10); // declare an object
cout<<A.year()<<endl; //const member function:2004
cout<<A.day()<<endl; //non-const member function:11
}
volatile关键字
volatile的意思是“该数据可能在编译器不知道的情况下发生变化。”
Volatile告诉编译器不要对数据做任何假设。
创建volatile对象的语法与创建const对象的语法相同。