修饰 C++ 成员函数的两种关键字总结

来源:互联网 发布:日本人看亮剑 知乎 编辑:程序博客网 时间:2024/06/05 17:59

修饰 C++ 成员函数的两种关键字总结

常量成员函数 (const 关键字)

const 修饰成员函数表示这个成员函数不能修改类的成员变量,因此这种成员函数称为常量成员函数。这样,编译器可以对这个函数进行深度的优化。另外,一个类的常量型示例只能调用常量型成员函数。比如下面这个例子。

class Test{public:    Test();    int getValue() const;    int value();private:    int intValue;};Test::Test():intValue(1){}int Test::getValue() const{    return intValue;}int Test::value(){    return intValue;}

类 Test 有 getValue() 和 value() 两个成员函数,其中一个是常量型的。那么下面的代码中:

int main(){    Test A;    const Test B;    cout << A.getValue() << endl;    cout << A.value() << endl;    cout << A.getValue() << endl;    cout << B.value() << endl;    return 0;}

B.value() 的访问就是非法的,因为 B 是常量,只能访问常量型成员函数。
作为一种良好的习惯,我们应该将类中所有不修改成员变量的函数都设为 const 型。

不过 const 型成员函数并非绝对不会改变类的成员。比如下面的代码:

#include <iostream> using namespace std;    char STRING[] = "A STRING!";class Test{public:    Test();    char * changeStr() const;private:    char *str;};Test::Test():  str(STRING){}char * Test::changeStr() const{    str[1] = 'x';    return str;}int main(){    const Test A;    cout <<  A.changeStr();    return 0;}

const 修饰符只能保证指针 str 指向的地址不被修改。而指向的字符串的值是可以随便改的。 如果将 str 从 char * 类型改为数组就不一样了。下面的代码无法编译。因为 str[1] = ‘x’ 这个操作是非法的。

#include <iostream>using namespace std;class Test{public:    Test();    char * changeStr() const ;private:    char str[10];};Test::Test(){    strcpy(str, "A STRING!");}char * Test::changeStr() const{    str[1] = 'x';    return str;}int main(){    Test A;    cout <<  A.changeStr();    return 0;}

volatile 成员函数

与 const 相反,volatile 表示这个函数里访问的变量可能由于其他原因发生改变。比如其他线程可能会对这些变量赋值,或者硬件会有写其他的机制改变这些变量的值。这时这样的函数就应该用 volatile 关键字修饰,相当于告诉编译器,这个函数里访问的变量的值随时都可能变化,所以不要做访问优化。下面是个例子,A 被定义为 volatile 型变量,A.value() 必须要定义为 volatile,否则不能访问。

#include <iostream>using namespace std;class Test{public:    Test();    int value() volatile;private:    int v;};Test::Test(){    v = 1;}int Test::value() volatile{    return v;}int main(){    volatile Test A;    cout <<  A.value() << endl;    return 0;}

volatile 和 const 也可以同时修饰一个函数。表示这个函数本身不修改变量的值,但是变量的值可能会自己变化。下面是例子:

#include <iostream>using namespace std;class Test{public:    Test();    int value() volatile const;private:    int v;};Test::Test(){    v = 1;}int Test::value() volatile const{    return v;}int main(){    volatile const Test A;    cout <<  A.value() << endl;    return 0;}
1 0