天天看点

面向对象技术与方法学习笔记-第八章Constants#define值替换指针函数参数和返回值临时变量类mutable关键字volatile关键字

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();
}
           
面向对象技术与方法学习笔记-第八章Constants#define值替换指针函数参数和返回值临时变量类mutable关键字volatile关键字

常量数据成员

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对象的语法相同。

继续阅读