C++ 中的 const 关键字详解:变量、指针及函数的应用

在 C/C++ 中,const 可以用于修饰变量、函数、指针等,主要作用有以下几种:
1. const 修饰变量
当const修饰变量时,该变量被视为只读,意味着其值在声明后不能被修改。这一特性对于确保不会意外更改某些不应变动的变量非常重要,同时也能帮助编译器进行更智能的代码优化。
例如:
const int a = 10; a = 20; // 编译错误,a 是只读变量,不能被修改
需要注意的是,尽管 const 提供了编译时的保护,但实际上仍可通过指针间接修改这些变量的值,这种做法虽然有效,但是不推荐。具体来说,可以通过将const int指针转换为int*类型来去掉const限制,从而改变变量的值。这种类型转换在 C++ 中称为const_cast。
然而,尽管可以进行这种操作,它会违反 const 的语义,可能导致程序崩溃或产生未定义行为(undefined behavior)。所以,了解这些操作是必要的,但在实际编程中应避免这样做。
此外,由于编译器可能对 const 变量进行优化,使用 const 时编译器可能直接将变量的常量值替换到代码中,而不是每次都访问变量。这意味着如果你通过指针修改了 const 变量的值,可能并不会如预期那样生效。因此,在编写代码时,应该始终遵循 const 的约定,以避免潜在的问题。
举个例子,使用 const_cast 修改 const 变量的值却不会起作用:
const int a = 10; const int* p = &a; int* q = const_cast<int*>(p); *q = 20; // 通过指针间接修改 const 变量的值 std::cout << "a = " << a << std::endl; // 输出 a 的值,结果为 10
在上面的例子中,将 p 声明为 const int* 类型,指向只读变量 a 的地址。
然后使用 const_cast 将 p 强制转换为int*类型的指针 q,从而去掉了 const 限制。
接下来,通过指针 q 间接修改了变量 a 的值。
但是请注意,即使 a 的值被修改了,但在程序中输出 a 的值仍然是 10,
正如前面所有,因为 a 是只读变量,所以编译器做了优化,早就把代码实际替换为了下面这样:
std::cout << "a = " << 10 << std::endl;
所以,咱们还是要老老实实按照语言标准编程,切莫搞各种骚操作。
总之,使用 const_cast 去掉 const 限制是不推荐的,这会破坏程序的正确性和稳定性。
我们应该遵循 C/C++ 语言中 const 的语义,尽量不修改只读变量的值。
2. const 修饰函数参数,表示函数不会修改参数
当 const 修饰函数参数时,表示函数内部不会修改该参数的值。这样做可以使代码更加安全,避免在函数内部无意中修改传入的参数值。
尤其是 引用 作为参数时,如果确定不会修改引用,那么一定要使用 const 引用。
例如:
void test(const int a) {
// 编译错误,不能修改 a 的值
a = 10;
}
3. const 修饰函数返回值
当 const 修饰函数返回值时,表示函数的返回值为只读,不能被修改。这样做可以使函数返回的值更加安全,避免被误修改。
例如:
const int test() {
int a = 100;
return a;
}
int main() {
const int b = test(); // b 的值为 100,不能被修改
b = 200; // 编译错误,b 是只读变量,不能被修改
return 0;
}
4. const 修饰指针或引用
在 C/C++ 中,const 关键字可以用来修饰指针,用于声明指针本身为只读变量或者指向只读变量的指针。
根据 const 关键字的位置和类型,可以将 const 指针分为以下三种情况:
4.1. 指向只读变量的指针
这种情况下,const 关键字修饰的是指针所指向的变量,而不是指针本身。
因此,指针本身可以被修改(意思是指针可以指向新的变量),但是不能通过指针修改所指向的变量。
const int* p; // 声明一个指向只读变量的指针,可以指向 int 类型的只读变量 int a = 10; const int b = 20; p = &a; // 合法,指针可以指向普通变量 p = &b; // 合法,指针可以指向只读变量 *p = 30; // 非法,无法通过指针修改只读变量的值
在上面的例子中,我们使用const int*声明了一个指向只读变量的指针 p。
我们可以将指针指向普通变量或者只读变量,但是无法通过指针修改只读变量的值。
4.2 只读指针
这种情况下,const 关键字修饰的是指针本身,使得指针本身成为只读变量。
因此,指针本身不能被修改(即指针一旦初始化就不能指向其它变量),但是可以通过指针修改所指向的变量。
int a = 100; int b = 200; int* const p = &a; // 声明一个只读指针,指向 a *p = 300; // 合法,可以通过指针修改 a 的值 p = &b; // 非法,无法修改只读指针的值
在上面的例子中,我们使用int* const声明了一个只读指针 p,指向变量 a。我们可以通过指针修改 a 的值,但是无法修改指针的值。
4.3 只读指针指向只读变量
这种情况下,const 关键字同时修饰了指针本身和指针所指向的变量,使得指针本身和所指向的变量都成为只读变量。
因此,指针本身不能被修改,也不能通过指针修改所指向的变量。
const int a = 10; const int* const p = &a; // 声明一个只读指针,指向只读变量 a *p = 20; // 非法,无法通过指针修改只读变量的值 p = nullptr; // 非法,无法修改只读指针的值
4.4 常量引用
常量引用是指引用一个只读变量的引用,因此不能通过常量引用修改变量的值。
const int a = 10; const int& b = a; // 声明一个常量引用,引用常量 a b = 20; // 非法,无法通过常量引用修改常量 a 的值
5. 修饰成员函数
const 修饰成员函数,从而指示该函数不会对类的成员变量进行修改。将成员函数声明为 const 是一种良好的编程习惯,它帮助提高代码的可读性和安全性,并允许对常量对象调用这些函数。
例如:
class MyClass {
public:
int getValue() const; // 声明为 const 成员函数
private:
int value;
};
const 成员函数的特性:
- 不修改成员变量:在 const 成员函数内部,不能修改类的非 const 成员变量。如果尝试修改将导致编译错误。
- 可调用于常量对象:只有 const 成员函数可以被 const 对象调用。这意味着如果你有一个常量对象,你只能调用其 const 成员函数。
注意事项:
- 能访问 const 成员变量:在 const 成员函数中,你可以读取类的成员变量,但不能修改它们。
- 重载问题:如果你有同名的成员函数,一个是 const 的,另一个不是,C++ 会根据对象是否为 const 来选择调用哪个版本。这意味着你可以在同一个类中定义两个重载的成员函数,一个用于常量对象,一个用于非常量对象。
以上关于C++ 中的 const 关键字详解:变量、指针及函数的应用的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » C++ 中的 const 关键字详解:变量、指针及函数的应用
微信
支付宝