C++中的const是一種常量修飾符。在變量、函數(shù)參數(shù)和成員函數(shù)中使用const可以限制其對(duì)數(shù)據(jù)的修改。
const修飾的數(shù)據(jù)在定義時(shí)必須進(jìn)行初始化,且不能被修改,因此使用const可以提高代碼的安全性和可讀性。在C++中,const修飾的成員函數(shù)表示該函數(shù)保證不會(huì)修改類的成員變量,從而保證對(duì)象的狀態(tài)不會(huì)被改變。使用const修飾的成員函數(shù)可以幫助程序員更好地實(shí)現(xiàn)不變類(不修改內(nèi)部狀態(tài)的類)和避免不必要的拷貝構(gòu)造函數(shù)的調(diào)用。
C++中使用`const`的主要目的是為了告訴編譯器某些變量或函數(shù)參數(shù)、類成員函數(shù)、關(guān)鍵字等不會(huì)被修改,從而提高代碼的可讀性、可維護(hù)性和安全性。使用`const`的主要注意事項(xiàng)如下:
1. 使用const修飾變量
使用const修飾變量時(shí),需要注意以下幾點(diǎn):
- 定義時(shí)必須進(jìn)行初始化,一旦初始化后,就不能再修改變量的值。
- const定義的常量存放在靜態(tài)存儲(chǔ)區(qū),而不是棧中。
- 通常采用const全大寫的命名方式來表示常量,提高可讀性。
- 在函數(shù)參數(shù)列表中,const修飾的參數(shù)表明函數(shù)不能修改該參數(shù)的值。
2. 在類中使用const修飾成員變量
在類中使用const修飾成員變量時(shí),需要注意以下幾點(diǎn):
- const成員變量必須在定義時(shí)進(jìn)行初始化,在構(gòu)造函數(shù)中無法進(jìn)行初始化。
- const成員變量只能通過成員初始化列表進(jìn)行初始化。
- 可以在構(gòu)造函數(shù)中通過調(diào)用其他函數(shù)或者使用默認(rèn)參數(shù)對(duì)const成員變量進(jìn)行初始化。
- const成員變量的值不能在構(gòu)造函數(shù)中被修改。
3. 在類中使用const修飾成員函數(shù)
在類中使用const修飾成員函數(shù)時(shí),需要注意以下幾點(diǎn):
- const成員函數(shù)不能修改類的非靜態(tài)成員變量。
- 如果類中有一個(gè)const成員函數(shù),那么該成員函數(shù)是類的常量成員函數(shù),只能被const對(duì)象調(diào)用,不能被非const對(duì)象調(diào)用。
- 具有相同名稱和參數(shù)的另外一個(gè)非const成員函數(shù)可以修改類的成員變量。
使用const可以使你的代碼更加安全、可讀性更高,并且有助于防止一些不必要的錯(cuò)誤。文章來源:http://www.zghlxwxcb.cn/news/detail-805035.html
為了避免const使用時(shí)出現(xiàn)的錯(cuò)誤,需要在使用時(shí)注意以上細(xì)節(jié),如常量的定義和初始化、使用const修飾的指針、const修飾的成員變量和成員函數(shù)、以及常量對(duì)象的初始化等細(xì)節(jié)。文章來源地址http://www.zghlxwxcb.cn/news/detail-805035.html
// const修飾變量
#include <iostream>
int main()
{
// 定義并初始化N
const int N = 10;
// 使用const修飾變量N,使其成為一個(gè)常量。因?yàn)镹是常量,所以可以用它定義數(shù)組并使用,但是在后面試圖修改N的值是會(huì)編譯錯(cuò)誤。
int arr[N];
for (int i = 0; i < N; i++)
{
arr[i] = i;
std::cout << arr[i] << " ";
}
std::cout << std::endl;
//const修飾的N不能修改, 編譯報(bào)錯(cuò),error: assignment of read-only variable ‘N’
// N = 20;
return 0;
}
// const修飾函數(shù)參數(shù)
#include <iostream>
// const修飾函數(shù)參數(shù)
void arrPrint(const int arr[], const int size)
{
for (int i = 0; i < size; i++)
{
std::cout << arr[i] << " ";
}
std::cout << std::endl;
// const修飾的參數(shù)不能修改,編譯報(bào)錯(cuò)試圖對(duì)只讀的數(shù)組元素進(jìn)行賦值。error: assignment of read-only location ‘* arr’
// arr[0] = 10;
// size = 6;
}
int main()
{
int arr[5] = {1, 2, 3, 4, 5};
int size = sizeof(arr) / sizeof(arr[0]);
arrPrint(arr, size);
return 0;
}
// const修飾成員函數(shù)
#include <iostream>
class Circle {
public:
// 常量數(shù)據(jù)成員通常不直接在聲明時(shí)初始化賦值,不合適,一般使用成員初始化列表進(jìn)行賦值
Circle(double r) : radius(r) {}
// const修飾成員函數(shù)
double getArea() const {
return 3.1415926 * radius * radius;
}
// const修飾成員函數(shù)
double getRadius() const {
// const修飾的radius不能修改,編譯報(bào)錯(cuò),error: assignment of member ‘Circle::radius’ in read-only object
// radius = 3;
return radius;
}
// const修飾數(shù)據(jù)成員
const double radius;
// 常量數(shù)據(jù)成員通常不直接在聲明時(shí)初始化賦值,不合適,一般使用成員初始化列表進(jìn)行賦值
// const double radius = 5.0;
};
int main()
{
Circle c(5.0);
std::cout << "radius : " << c.getRadius() << std::endl;
std::cout << "area : " << c.getArea() << std::endl;
// const修飾的radius不能修改,編譯報(bào)錯(cuò),error: assignment of read-only member ‘Circle::radius’
// c.radius = 3;
return 0;
}
// const修飾的類枚舉
#include <iostream>
class Shape {
public:
enum class Type : int {
Circle = 0,
Square = 1,
};
Shape(Type t) : type(t) {}
void getType() const {
switch (type)
{
case Type::Circle:
std::cout << "circle" << std::endl;
break;
case Type::Square :
std::cout << "square" << std::endl;
default:
break;
}
}
// const修飾的類枚舉
const Type type;
};
int main()
{
// 創(chuàng)建Shape對(duì)象,指定類型為Circle
Shape c(Shape::Type::Circle);
c.getType();
Shape s(Shape::Type::Square);
s.getType();
// const修飾的類枚舉不能修改,編譯錯(cuò)誤,error: assignment of read-only member ‘Shape::type’
// c.type = Shape::Type::Square;
return 0;
}
// const修飾的靜態(tài)類變量
#include <iostream>
class Counter {
public:
Counter() {
count++;
}
Counter(const Counter & c) {
count++;
}
static int getCount() {
return count;
}
private:
// const修飾的靜態(tài)成員變量
static const int LIMIT = 10;
// 類靜態(tài)變量
static int count;
};
// 定義靜態(tài)成員變量
int Counter::count = 0;
int main()
{
Counter c1, c2, c3;
std::cout << "count : " << Counter::getCount() << std::endl;
// const修飾的類靜態(tài)變量不能修改,編譯錯(cuò)誤,error: assignment of read-only variable ‘Counter::LIMIT’
// Counter::LIMIT = 20;
return 0;
}
// const修飾的非靜態(tài)成員函數(shù)
#include <iostream>
class Circle{
public:
Circle(double r) : radius(r) {}
double getArea() const {
return PI * radius * radius;
}
double getRadius() const {
return radius;
}
private:
// 定義靜態(tài)常量
static const double PI;
double radius;
};
const double Circle::PI = 3.1415926;
int main()
{
const Circle c(5.0);
std::cout << "area : " << c.getArea() << std::endl;
return 0;
}
// const修飾的類轉(zhuǎn)換函數(shù)
#include <iostream>
class Point {
public:
Point(int x, int y) : _x(x), _y(y) {}
int getX() const {
return _x;
}
int getY() const {
return _y;
}
// 類中定義了一個(gè)使用const修飾的類轉(zhuǎn)換函數(shù):`operator int()`。
// 該函數(shù)將一個(gè)Point對(duì)象轉(zhuǎn)換為一個(gè)整數(shù),這里我們將`_x`和`_y`簡單地相加。
// 在`main()`函數(shù)中,我們創(chuàng)建了一個(gè)`Point`對(duì)象,并將其轉(zhuǎn)換為整數(shù)輸出。
// 由于在類轉(zhuǎn)換函數(shù)中使用了const修飾,保證了不會(huì)修改對(duì)象
operator int() const {
return _x + _y;
}
private:
int _x;
int _y;
};
int main()
{
Point p(3, 4);
std::cout << static_cast<int>(p) << std::endl;
return 0;
}
// const在函數(shù)前面修飾
// 在C++中,const可以用在函數(shù)的前面和后面,
// 用在函數(shù)后面是用來修飾成員函數(shù),用在函數(shù)前面則是用來修飾函數(shù)返回值。它們的區(qū)別在于const的含義不同。
// const修飾成員函數(shù)和修飾函數(shù)返回值都能達(dá)到保護(hù)數(shù)據(jù)不被修改的目的,但用法和意義不同。必須根據(jù)實(shí)際情況選擇適當(dāng)?shù)男揎棥?// const在函數(shù)前面為常量函數(shù),const在函數(shù)后面為常量成員函數(shù)
// 常量成員函數(shù)用于定義不能修改任何非靜態(tài)成員數(shù)據(jù)的函數(shù)(或稱“只讀”函數(shù)),而常量函數(shù)用于定義不能修改其返回值的函數(shù),使返回值更安全。
#include <iostream>
class Rectangle {
public:
Rectangle(int w, int h) : width(w), height(h) {}
// const在函數(shù)后面用來修飾成員函數(shù),表示該成員函數(shù)是一個(gè)常量成員函數(shù),不能修改類的非靜態(tài)成員變量。
// 常量成員函數(shù)也不能被非const對(duì)象調(diào)用。
int getArea() const;
// 返回值類型為`const int &`,表示返回的是一個(gè)常量引用,不能修改它所引用的變量。
// const在函數(shù)前面用來修飾函數(shù)返回值,表示該函數(shù)返回的值是一個(gè)常量。
// 通常用于返回一個(gè)常量指針或常量引用,以避免返回值被修改。
const int &max(const int &a, const int &b) {
return (a > b) ? a : b;
}
// C++中`const`關(guān)鍵字可以用在函數(shù)返回值的前面或后面,
// 用在函數(shù)返回類型前面就表示返回值是一個(gè)`const`常量,用在類型后面表示該函數(shù)是一個(gè)常量函數(shù)。
// 所以`int const func()`和`const int func()`是等同的,它們都表示一個(gè)返回值是`const int`類型的函數(shù)。
// 這種用法通常用于返回一個(gè)常量對(duì)象,或常量指針、常量引用等等,以避免返回值被修改。
const int get100() {
return 100;
}
int const get200() {
// const修飾的是返回值,函數(shù)可以修改成員變量的值
this->width = 200;
return 200;
}
int getWidth() const {
// 函數(shù)被聲明為常量成員函數(shù),因此不能修改成員變量的值
// 不能修改成員變量,編譯錯(cuò)誤,error: assignment of member ‘Rectangle::m_val’ in read-only object
// this->m_val = 100;
return this->width;
}
void setValue(int value) {
this->width = value;
}
// 當(dāng)`const`關(guān)鍵字放在成員函數(shù)的前面時(shí),它修飾的是函數(shù)的返回值,表示這個(gè)函數(shù)的返回值是一個(gè)常量。
// 這種函數(shù)返回類型前加`const`關(guān)鍵字的寫法,通常用于返回一個(gè)常量整數(shù)、常量指針或常量引用等,以避免返回值被修改。
// 常量函數(shù)的常量限制作用于函數(shù)的返回值上,而非函數(shù)的實(shí)現(xiàn)代碼中。
// 函數(shù)的返回值類型被定義成`const int`,表明函數(shù)返回了一個(gè)常量整數(shù)
const int getHeight() const {
return this->height;
}
private:
int width, height;
};
// 常成員函數(shù),在函數(shù)尾部加const,常成員函數(shù)在類外實(shí)現(xiàn)的時(shí)候const不能丟掉,因?yàn)閏onst時(shí)函數(shù)的一部分
// 在常成員函數(shù)中不能修改任何數(shù)據(jù)成員的值,常成員函數(shù)內(nèi)不能對(duì)類的任何數(shù)據(jù)成員進(jìn)行修改,
// 即當(dāng)前類中凡是能用this指出來的成員都改不了,但是可以訪問,就是只能看不能改,但是靜態(tài)成員變量可以修改。
int Rectangle::getArea() const {
// error: assignment of member ‘Rectangle::width’ in read-only object
// width = 10;
return width * height;
}
int main()
{
const Rectangle r(5, 10);
std::cout << "area : " << r.getArea() << std::endl;
// const放函數(shù)前面
Rectangle r1(5, 10);
// 常量引用`maxVal`來引用`max()`函數(shù)返回的值,因此不能修改`maxVal`的值。
// 報(bào)錯(cuò),error: passing ‘const Rectangle’ as ‘this’ argument discards qualifiers [-fpermissive]
// const int & max = r.max(5, 10);
const int & maxVal = r1.max(5, 10);
// error: assignment of read-only reference ‘maxVal’
// maxVal = 20;
std::cout << "max val : " << maxVal << std::endl;
// 報(bào)錯(cuò),error: passing ‘const Rectangle’ as ‘this’ argument discards qualifiers [-fpermissive]
// r.get100();
const int a1 = r1.get100();
// 報(bào)錯(cuò),error: expected initializer before ‘a(chǎn)2’
// 這個(gè)錯(cuò)誤是因?yàn)閌r1`對(duì)象是一個(gè)`const`對(duì)象,在`const`對(duì)象上調(diào)用非常量成員函數(shù)是不允許的,
// 因?yàn)榉浅A砍蓡T函數(shù)可以修改對(duì)象的狀態(tài),會(huì)破壞對(duì)象的不可變性。
// int cosnt a2 = r1.get100();
std::cout << "get100 : " << r1.get100() << std::endl;
std::cout << "get200 : " << r1.get200() << std::endl;
// 創(chuàng)建了一個(gè)常量對(duì)象`obj`,也不能修改其中的成員變量。
const Rectangle obj0(10, 20);
std::cout << obj0.getWidth() << std::endl;
// 不能修改常量對(duì)象的成員變量,編譯錯(cuò)誤,error: passing ‘const Rectangle’ as ‘this’ argument discards qualifiers [-fpermissive]
// obj0.setValue(10);
Rectangle obj1(10, 30);
std::cout << obj1.getHeight() << std::endl;
// 通過調(diào)用常量函數(shù)`obj.getValue()`來獲取常量整數(shù)值,并將結(jié)果保存到一個(gè)常量值`value`中,這樣可以防止常量值被修改。
int a3 = obj1.getHeight();
const int a4 = obj1.getHeight();
std::cout << "a3 = " << a3 << ", a4 = " << a4 << std::endl;
return 0;
}
// 常量成員函數(shù)和常量函數(shù)的區(qū)別
// - 常量成員函數(shù)在函數(shù)聲明的結(jié)尾處加上`const`修飾符,用于定義不會(huì)修改任何非靜態(tài)成員數(shù)據(jù)的函數(shù)。
// 也就是說,常量成員函數(shù)將其所操作的對(duì)象指定為常量,從而導(dǎo)致它不能在函數(shù)調(diào)用中修改類中的任何非靜態(tài)成員變量。
// - 常量函數(shù)在函數(shù)返回類型前加上`const`修飾符,用于定義不能修改其返回值的函數(shù)。
// 也就是說,常量函數(shù)指定了函數(shù)返回的值是一個(gè)常量,無法被修改。
#include <iostream>
class Rectangle {
public:
Rectangle(int width, int height) : m_width(width), m_height(height) {}
// 常量成員函數(shù)
int getArea() const;
int getValue() const;
void setValue(int value);
// 常量函數(shù)
int const getWidth() const {
return m_width;
}
const int getHeight() const {
return m_height;
}
const int get100() {
return m_height;
}
const int get200() {
return m_height;
}
private:
int m_width;
int m_height;
int m_value;
};
// 常成員函數(shù),在函數(shù)尾部加const,常成員函數(shù)在類外實(shí)現(xiàn)的時(shí)候const不能丟掉,因?yàn)閏onst時(shí)函數(shù)的一部分
// 在常成員函數(shù)中不能修改任何數(shù)據(jù)成員的值,常成員函數(shù)內(nèi)不能對(duì)類的任何數(shù)據(jù)成員進(jìn)行修改,
// 即當(dāng)前類中凡是能用this指出來的成員都改不了,但是可以訪問,就是只能看不能改,但是靜態(tài)成員變量可以修改。
int Rectangle::getArea() const {
return m_width * m_height;
}
int Rectangle::getValue() const {
return m_value;
}
void Rectangle::setValue(int value) {
m_value = value;
}
int main()
{
// c++非常量對(duì)象可以調(diào)用類的常量成員函數(shù),常量對(duì)象不能調(diào)用非常量成員函數(shù)
const Rectangle r(3, 4);
// 調(diào)用常量成員函數(shù)
std::cout << "Area: " << r.getArea() << std::endl;
// 調(diào)用常量函數(shù)
const int value = r.getValue();
std::cout << "Value: " << value << std::endl;
// 不能在常量對(duì)象上調(diào)用非常量成員函數(shù)
// r.setValue(5); // 編譯錯(cuò)誤
const Rectangle r1(10, 20);
std::cout << "width : " << r1.getWidth() << ", height : " << r1.getHeight() << std::endl;
// 常量對(duì)象不能調(diào)用非常量成員函數(shù),報(bào)錯(cuò),error: no matching function for call to ‘Rectangle::setValue() const’
// r1.setValue();
// r1.get100();
// r1.get200();
return 0;
}
// const常量對(duì)象
// C++中,如果對(duì)象被聲明為常量對(duì)象,那么就意味著該對(duì)象的值不能被修改。
// 常量對(duì)象是指對(duì)象在創(chuàng)建后,其值被確定不變,不允許被修改。
// 非常量對(duì)象可以調(diào)用常量成員函數(shù),因?yàn)槌A砍蓡T函數(shù)不會(huì)修改對(duì)象的狀態(tài),所以沒有任何風(fēng)險(xiǎn)和限制。
// 而常量對(duì)象不能調(diào)用非常量成員函數(shù),因?yàn)榉浅A砍蓡T函數(shù)有可能會(huì)修改對(duì)象的狀態(tài),這會(huì)與常量對(duì)象的定義相矛盾,所以編譯器會(huì)拒絕這樣的調(diào)用并報(bào)錯(cuò)。
#include <iostream>
class Rectangle {
public:
Rectangle(int width, int height) : m_width(width), m_height(height) {}
int getArea() const;
void setValue(int value);
private:
int m_width;
int m_height;
};
// 常成員函數(shù),在函數(shù)尾部加const,常成員函數(shù)在類外實(shí)現(xiàn)的時(shí)候const不能丟掉,因?yàn)閏onst時(shí)函數(shù)的一部分
// 在常成員函數(shù)中不能修改任何數(shù)據(jù)成員的值,常成員函數(shù)內(nèi)不能對(duì)類的任何數(shù)據(jù)成員進(jìn)行修改,
// 即當(dāng)前類中凡是能用this指出來的成員都改不了,但是可以訪問,就是只能看不能改,但是靜態(tài)成員變量可以修改。
int Rectangle::getArea() const {
return m_width * m_height;
}
void Rectangle::setValue(int value) {
m_width = value;
m_height = value;
}
int main() {
Rectangle r1(2, 3); // 非常量對(duì)象
// 在C++中,`const`關(guān)鍵字可以用在類型的右側(cè)或左側(cè)。
// 當(dāng)`const`關(guān)鍵字出現(xiàn)在類型名稱的左側(cè)時(shí),它會(huì)作用于變量名之前的類型部分;
// 當(dāng)`const`關(guān)鍵字出現(xiàn)在類型名稱的右側(cè)時(shí),它會(huì)作用于變量名之后的類型部分。
// int const b = 20; // 常量整數(shù),等價(jià)于const int b = 20;
// Rectangle const r3(5, 6); // 常量對(duì)象,值不可修改,等價(jià)于const Rectangle r3(5, 6);
const Rectangle r2(3, 4); // 常量對(duì)象
Rectangle const r3(5, 6); // 常量對(duì)象
r1.getArea(); // 非常量對(duì)象調(diào)用常量成員函數(shù)
r2.getArea(); // 常量對(duì)象調(diào)用常量成員函數(shù)
// r2.setValue(5); // 編譯錯(cuò)誤,常量對(duì)象不能調(diào)用非常量成員函數(shù)
r1.setValue(5); // 非常量對(duì)象可以調(diào)用非常量成員函數(shù)
return 0;
}
到了這里,關(guān)于c++關(guān)鍵字const的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!