《c/c++中的const》——含義和用法

const概述

const單詞字面意思爲常數,不變的。它是c/c++中的一個關鍵字,是一個限定符,它用來限定一個變量不允許改變,它將一個對象轉換成一個常量。

const int a = 10;
A = 100; //編譯錯誤,const是一個常量,不可修改

C中的const

常量的引進是在c++早期版本中,當時標準C規範正在制定。那時,儘管C委員會決定在C中引入const,但是,他們c中的const理解爲”一個不能改變的普通變量”,也就是認爲const應該是一個只讀變量,

  • 既然是變量那麼就會給const分配內存
  • 並且在c中const是一個全局只讀變量
  • c語言中const修飾的只讀變量是外部連接的(也就是說它在該文件外可見)。
const int max= 10;
int arr[max];//看似是一件合理的編碼,但是這將得出一個錯誤。 因爲max佔用某塊內存,所以C編譯器不知道它在編譯時的值是多少

C++中的const

  1. 在c++中,一個const不必創建內存空間,而在c中,一個const總是需要一塊內存空間
  2. 在c++中,是否爲const常量分配內存空間依賴於如何使用。一般說來,如果一個const僅僅用來把一個名字用一個值代替(就像使用#define一樣),那麼該存儲局空間就不必創建
  3. 如果存儲空間沒有分配內存的話,在進行完數據類型檢查後,爲了代碼更加有效,值也許會摺疊到代碼中
  4. 不過,取一個const地址, 或者把它定義爲extern,則會爲該const創建內存空間
  5. 在c++中,出現在所有函數之外的const作用於整個文件(也就是說它在該文件外不可見),默認爲內部連接,c++中其他的標識符一般默認爲外部連接

C/C++中const異同總結

  1. c語言全局const會被存儲到只讀數據段。c++中全局const當聲明extern或者對變量取地址時,編譯器會分配存儲地址,變量存儲在只讀數據段。兩個都受到了只讀數據段的保護,不可修改。
  2. c語言中局部const存儲在堆棧區,只是不能通過變量直接修改const只讀變量的值,但是可以跳過編譯器的檢查,通過指針間接修改const值。
  3. c++中對於局部的const變量要區別對待:
- 對於基礎數據類型,也就是const int a = 10這種,編譯器會進行優化,將值替換到訪問的位置。**相當於宏替換**
- 對於基礎數據類型,如果用一個變量初始化const變量,如果const int a = b,那麼也是會給a分配內存。
- 對於自定數據類型,比如類對象,那麼也會分配內存
  1. c中const默認爲外部連接,c++中const默認爲內部連接.當c語言兩個文件中都有const int a的時候,編譯器會報重定義的錯誤。而在c++中,則不會,因爲c++中的const默認是內部連接的。如果想讓c++中的const具有外部連接,必須顯示聲明爲: extern const int a = 10;
  2. const由c++採用,並加進標準c中,儘管他們很不一樣。在c中,編譯器對待const如同對待變量一樣,只不過帶有一個特殊的標記,意思是”你不能改變我”。在c中定義const時,編譯器爲它創建空間,所以如果在兩個不同文件定義多個同名的const,鏈接器將發生鏈接錯誤。簡而言之,const在c++中用的更好

儘量以const替換#define

在舊版本C中,如果想建立一個常量,必須使用預處理器”

#define MAX 1024;

我們定義的宏MAX從未被編譯器看到過,因爲在預處理階段,所有的MAX已經被替換爲了1024,於是MAX並沒有將其加入到符號表中。但我們使用這個常量獲得一個編譯錯誤信息時,可能會帶來一些困惑,因爲這個信息可能會提到1024,但是並沒有提到MAX.如果MAX被定義在一個不是你寫的頭文件中,你可能並不知道1024代表什麼,也許花費很長時間去追蹤查看。
解決辦法就是用一個常量替換上面的宏。

const int max= 1024;

const和#define區別總結:

1.const有類型,可進行編譯器類型安全檢查。#define無類型,不可進行類型檢查.
2.const有作用域,而#define不重視作用域,默認定義處到文件結尾.如果定義在指定作用域下有效的常量,那麼#define就不能用

const在類中的使用

const修飾成員函數(常函數)

  1. 用const修飾的成員函數時,const修飾this指針指向的內存區域,成員函數體內不可以修改本類中的任何普通成員變量
  2. 當成員變量類型符前用mutable修飾時例外。
//const修飾成員函數
class A{
public:
	A(){
		this->mAge = 0;
		this->mID = 0;
	}
	//在函數括號後面加上const,修飾成員變量不可修改,除了mutable變量
	void sonmeOperate() const
	{
		//this->mAge = 200; //mAge不可修改
		//this->mKG = 65; //mKG本身就是常量不可修改
		this->mID = 10; //const Person* const tihs;
	}
	void ShowPerson(){
		cout << "ID:" << mID << " mAge:" << mAge << endl;
	}
private:
	int mAge;
	const int mKG;//本身就是常量,常函數和非常函數都不能改
	mutable int mID;
};

const修飾對象(常對象)

  • 常對象只能調用const的成員函數
  • 常對象可訪問 const 或非 const 數據成員,不能修改,除非成員用mutable修飾
class A{
public:
	A(){
		this->mAge = 0;
		this->mID = 0;
	}
	//在函數括號後面加上const,修飾成員變量不可修改,除了mutable變量
	void sonmeOperate() const
	{
		//this->mAge = 200; //mAge不可修改
		//this->mKG = 65; //mKG本身就是常量不可修改
		this->mID = 10; //const Person* const tihs;
	}
	void ShowPerson(){
		cout << "ID:" << mID << " mAge:" << mAge << endl;
	}
private:
	int mAge;
	const int mKG;//本身就是常量,常函數和非常函數都不能改
	mutable int mID;
};
void test(){	
	const A person;
	//1. 可訪問數據成員
	cout << "Age:" << person.mAge << endl;
	//person.mAge = 300; //不可修改
	person.mID = 1001; //但是可以修改mutable修飾的成員變量
	//2. 只能訪問const修飾的函數
	//person.ShowPerson();
	person.ChangePerson();
}



版權聲明:拷貝、轉載請附上本文連接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章