成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

大廠一面:我說 Const 一般放在類型左側(cè),他意味深長的'哦'了一聲...面試官到底在暗示什么?

開發(fā)
? 東 Const 與 西 Const 是兩種表達 const 限定符位置的風格,功能等價,各有優(yōu)劣。西 Const 更常見,東 Const 規(guī)則更統(tǒng)一。

在 C++ 的編程實踐中,const 關(guān)鍵字扮演著至關(guān)重要的角色。它不僅是實現(xiàn)常量語義、保護數(shù)據(jù)不被意外修改的基石,更是接口設(shè)計、編譯器優(yōu)化和代碼意圖表達的關(guān)鍵工具。

然而,這個看似簡單的關(guān)鍵字,其在代碼中的書寫位置卻引發(fā)了一場曠日持久的風格之爭——即所謂的“東 const 派”(East Const / Right Const)與“西 const 派”(West Const / Left Const)。

一、西 Const 派 (West Const / Left Const):約定俗成的起點

"西 const"風格是許多 C++ 開發(fā)者學習 C++ 時首先接觸到的形式。它的核心規(guī)則是:const 關(guān)鍵字通常放置在它所修飾的類型名稱的左側(cè)(西邊)。

1. 基本示例:

#include <string>
#include <vector>
#include <cassert>

// 1. 基本類型的常量
const int MAX_USERS = 1000;        // 一個整型常量
const double PI = 3.14159;       // 一個雙精度浮點常量
const bool IS_ENABLED = true;    // 一個布爾常量

// 2. 常量引用 (Reference to Const)
const std::string GREETING = "Hello, World!";
const std::string& ref_greeting = GREETING; // 引用一個常量字符串,不能通過 ref_greeting 修改 GREETING

void printMessage(const std::string& msg){ // 函數(shù)參數(shù)為常量引用,保證函數(shù)內(nèi)部不修改傳入的字符串
    // msg = "Cannot change"; // 編譯錯誤:不能修改 const 引用指向的內(nèi)容
    std::cout << msg << std::endl;
}

// 3. 指向常量的指針 (Pointer to Const)
const int* ptr_to_const_int; // ptr_to_const_int 是一個指針,它指向一個常量 int
int value = 10;
ptr_to_const_int = &value;   // 指針可以指向一個非 const 變量...
// *ptr_to_const_int = 20;   // 編譯錯誤:不能通過 ptr_to_const_int 修改所指向的值
const int const_value = 20;
ptr_to_const_int = &const_value; // ...也可以指向一個 const 變量

// 指針本身是可變的
int another_value = 30;
ptr_to_const_int = &another_value; // 合法:讓指針指向另一個 int (即使是 const int*)

2. 解讀西 Const:

這種風格的直觀性在于,const 緊跟在類型之前,讀起來像是"一個常量整數(shù)"、"一個常量字符串的引用"或"一個指向常量整數(shù)的指針"。這在簡單情況下非常自然。

3. 西 Const 的復(fù)雜性:常量指針

當 const 不僅修飾指向的內(nèi)容,還要修飾指針本身時,西 Const 的寫法需要特別注意 const 的位置:

int score = 90;
int highScore = 100;

// 4. 常量指針 (Const Pointer)
int* const const_ptr = &score; // const_ptr 是一個常量指針,它*總是*指向 score
                               // const 修飾的是 ptr 本身,不是 *ptr

*const_ptr = 95;          // 合法:可以通過常量指針修改其指向的 *非 const* 內(nèi)容
// const_ptr = &highScore; // 編譯錯誤:不能改變常量指針的指向

// 5. 指向常量的常量指針 (Const Pointer to Const)
const int MAX_SCORE = 100;
const int* const const_ptr_to_const = &MAX_SCORE; // 指針本身和它指向的內(nèi)容都是常量

// *const_ptr_to_const = 99; // 編譯錯誤:不能修改指向的 const 內(nèi)容
// const_ptr_to_const = &value; // 編譯錯誤:不能改變常量指針的指向

在西 Const 風格下,const int* ptr 和 int* const ptr 的區(qū)別對于開發(fā)者來說可能是一個常見的混淆點。const 的位置決定了它是限制了"指針指向的內(nèi)容"還是"指針本身"。

二、 東 Const 派 (East Const / Right Const):追求一致性的規(guī)則

"東 const"風格的支持者認為,將 const 放在類型的右側(cè)(東邊)能夠提供一種更統(tǒng)一、更少歧義的解讀方式。其核心規(guī)則是:const 關(guān)鍵字修飾其緊鄰左側(cè)的內(nèi)容。

1. 基本示例 (與西 Const 等價):

#include <string>
#include <vector>
#include <type_traits> // 用于 static_assert 證明等價性

// 1. 基本類型的常量
int const MAX_USERS_EAST = 1000;
static_assert(std::is_same_v<constint, intconst>, "const int == int const"); // 證明類型等價

// 2. 常量引用 (Reference to Const)
std::string const GREETING_EAST = "Hello, East!";
std::string const& ref_greeting_east = GREETING_EAST;
static_assert(std::is_same_v<const std::string&, std::string const&>, "const T& == T const&");

void printMessageEast(std::string const& msg){
    // msg = "Cannot change"; // 編譯錯誤
    std::cout << msg << std::endl;
}

// 3. 指向常量的指針 (Pointer to Const)
int const* ptr_to_const_int_east;
static_assert(std::is_same_v<constint*, intconst*>, "const int* == int const*");

int value_east = 10;
ptr_to_const_int_east = &value_east;
// *ptr_to_const_int_east = 20; // 編譯錯誤

2. 關(guān)鍵等價性: 對于基本類型、常量引用、指向常量的指針,const T 和 T const 是完全等價的,編譯器將它們視為同一種類型。const T* 和 T const* 也是完全等價的。

3. 東 Const 的解讀優(yōu)勢

讓我們用"const 修飾左側(cè)"的規(guī)則來重新審視指針的情況:

(1) 指向常量的指針 (Pointer to Const):

int const* ptr;

解讀:const 修飾其左邊的 int。所以 ptr 是一個指針 (*),指向一個 int,這個 int 是 const 的。

(2) 常量指針 (Const Pointer):

int* const ptr = &score;

解讀:const 修飾其左邊的 *(指針)。所以 ptr 是一個 const 的指針 (*),它指向一個 int。指針本身是常量,不能改變指向。

(3) 指向常量的常量指針 (Const Pointer to Const):

int const* const ptr = &MAX_SCORE; 

解讀: 第一個 const (從右往左看) 修飾其左邊的 * (指針)。表示 ptr 是一個常量指針。 第二個 const (繼續(xù)往左) 修飾其左邊的 int。表示這個指針指向一個 const 的 int。

這種從右向左或遵循“const 修飾左側(cè)”的閱讀方式,在東 Const 風格下顯得尤為一致和清晰。

對比表格:

含義

西 Const

東 Const

"修飾左側(cè)"規(guī)則解讀 (東 Const)

指向常量的指針

const T* ptr

T const* ptr

ptr is a * to (T which is const)

常量指針

T* const ptr

T* const ptr

ptr is a (* which is const) to T

指向常量的常量指針

const T* const ptr

T const* const ptr

ptr is a (* which is const) to (T which is const)

東 Const 的支持者(包括一些 C++ 標準委員會成員和資深開發(fā)者,如 Bjarne Stroustrup 在某些場合也推薦)認為,這種一致性在處理更復(fù)雜的類型聲明(如函數(shù)指針、成員函數(shù)指針)時尤其有價值,減少了特殊規(guī)則記憶的負擔。

三、核心概念:頂層 Const (Top-Level) 與 底層 Const (Low-Level)

其實不管我們習慣東 Const 還是西 Const,要真正掌握 const 的行為,理解 頂層 const 和 底層 const 的區(qū)別至關(guān)重要。這個概念與東西風格無關(guān),而是關(guān)乎 const 修飾的是對象本身還是其所指向或引用的內(nèi)容。

  • 頂層 const (Top-Level Const): 表示對象本身是常量。這適用于任何類型的對象。
const int x = 10; // x 本身是常量,具有頂層 const。
int* const ptr = &some_int; // ptr 本身是常量(不能改變指向),具有頂層 const。指針指向的 int 不是常量。
const std::vector<int> vec = {1, 2, 3}; // vec 本身是常量,具有頂層 const。
  • 底層 const (Low-Level Const): 表示指針或引用所指向(或引用)的對象是常量。這只與復(fù)合類型(如指針、引用)相關(guān)。
const int* ptr; // ptr 指向的 int 是常量,具有底層 const。ptr 本身不是常量(可以改變指向)。int const* ptr; // 同上,底層 const。
const int& ref = x; // ref 引用的 int 是常量,具有底層 const。引用本身總是“常量”(不能重新綁定),但我們通常不稱引用本身有頂層 const。
int* const* ptr_ptr; // ptr_ptr 指向一個 int* const(常量指針)。這里的 const 是底層 const (相對于 ptr_ptr 而言,它指向的對象類型中帶有 const)。
const int* const ptr; // ptr 既有頂層 const (指針本身不能改),也有底層 const (指向的 int 不能改)。

為什么區(qū)分頂層與底層 Const 很重要?

(1) 拷貝與賦值操作: 當進行對象拷貝時(包括函數(shù)傳值參數(shù)),頂層 const 通常會被忽略。

const int a = 10;
int b = a; // 合法:a 的頂層 const 被忽略,拷貝的是值 10

int i = 0;
int* const p1 = &i; // p1 有頂層 const
int* p2 = p1;      // 合法:拷貝指針地址時,p1 的頂層 const 被忽略

底層 const 則必須被保留或加強,不能丟失。

const int c = 20;
const int* p_const = &c; // 底層 const
// int* p_non_const = p_const; // 編譯錯誤:不能將 const int* 賦給 int* (試圖丟棄底層 const)

int d = 30;
int* p_d = &d;
const int* p_const_d = p_d; // 合法:可以從 int* 轉(zhuǎn)換為 const int* (增加底層 const)

const int& r_const = c; // 底層 const
// int& r_non_const = r_const; // 編譯錯誤:不能將 const int& 綁定到 int&

(2) 函數(shù)重載: 函數(shù)可以根據(jù)參數(shù)的底層 const 進行重載。

void process(int* ptr);       // 處理非 const int 的指針
void process(const int* ptr); // 重載版本:處理 const int 的指針

int num = 1;
const int cnum = 2;
process(&num);  // 調(diào)用 process(int*)
process(&cnum); // 調(diào)用 process(const int*)

函數(shù)不能僅根據(jù)參數(shù)的頂層 const 進行重載(對于按值傳遞或指針/引用本身的頂層 const)。

// void setup(int x);
// void setup(const int x); // 編譯錯誤:重定義。參數(shù) x 的頂層 const 在函數(shù)簽名中被忽略

// void configure(int* p);
// void configure(int* const p); // 編譯錯誤:重定義。參數(shù) p 的頂層 const 被忽略

(3) 特殊: 成員函數(shù)的 const 限定符(void MyClass::func() const;)實際上是改變了隱式 this 指針的類型,為其添加了底層 const (從 MyClass* 變?yōu)?nbsp;const MyClass* 或 MyClass const*),因此可以基于此進行重載。

class Widget {
public:
    void update(){ /* ... */ }      // 可以修改對象狀態(tài)
    void display()const{ /* ... */ } // 保證不修改對象狀態(tài) (this 是 const Widget*)
};

Widget w;
const Widget cw;
w.update();    // OK
w.display();   // OK, 調(diào)用 display() const
// cw.update(); // 編譯錯誤:不能在 const 對象上調(diào)用非 const 成員函數(shù)
cw.display();  // OK, 調(diào)用 display() const

(4) 模板類型推導(dǎo):

模板參數(shù)推導(dǎo)時,頂層 const 通常會被忽略,而底層 const 會被保留。

template<typename T>
void foo(T param);

const int ci = 0;
foo(ci); // T 推導(dǎo)為 int (頂層 const 被忽略)

const int* pci = &ci;
foo(pci); // T 推導(dǎo)為 const int* (底層 const 被保留)

int* const cpi = &some_int;
foo(cpi); // T 推導(dǎo)為 int* (頂層 const 被忽略)

(5) 將頂層/底層 Const 與 East/West 聯(lián)系起來:

無論使用哪種風格,const 的位置都明確地指示了它是頂層還是底層:

T const* ptr / const T* ptr: const 應(yīng)用于 T,是底層 const。
T* const ptr: const 應(yīng)用于 * (指針本身),是頂層 const。
T const* const ptr / const T* const ptr: 第一個 const (靠近 T) 是底層 const,第二個 const (靠近 ptr) 是頂層 const。
const T x / T const x: const 應(yīng)用于對象 x 本身,是頂層 const。
const T& ref / T const& ref: const 應(yīng)用于 T (被引用的類型),是底層 const。

理解了頂層與底層 const 的概念,就能準確把握 const 在各種聲明中的含義,而東 const 或西 const 只是表達這些含義的兩種語法風格。

四、 風格選擇與一致性的重要性

既然東 Const 和西 Const 在功能上完全等價,并且都能表達頂層與底層 const 的語義,那么該如何選擇?

(1) 西 Const (Left Const): 

  • 優(yōu)點: 更為常見,尤其是在老代碼庫和許多入門教程中;對于簡單類型 (const int) 的閱讀可能更符合自然語言習慣。
  • 缺點: 在復(fù)雜指針聲明中,const 的位置規(guī)則不如東 Const 統(tǒng)一,可能需要更多思考來區(qū)分常量指針和指向常量的指針。

(2) 東 Const (Right Const): 

  • 優(yōu)點: 遵循單一、一致的"const 修飾左側(cè)"規(guī)則,有助于系統(tǒng)性地解讀復(fù)雜聲明;被一些專家和風格指南推薦,認為更具邏輯性。 
  • 缺點: 不如西 Const 普及,初學者可能不太習慣;對于最簡單的 const int,寫法 int const 可能感覺略微冗余。

(3) 最終的建議:一致性壓倒一切!

在技術(shù)層面上,沒有哪種風格是絕對"正確"或"錯誤"的。最重要的原則是在一個項目、一個團隊,甚至個人的代碼庫中保持一致性 。

  • 團隊項目: 遵循團隊既定的編碼規(guī)范。如果規(guī)范未明確,應(yīng)進行討論并達成一致?;旌鲜褂脙煞N風格會嚴重降低代碼的可讀性和可維護性。
  • 個人項目: 選擇認為更清晰、更能幫助準確理解代碼的風格,并堅持使用。甚至完全可以普通類型的變量用西 const,涉及到指針類型那么就用東 const
  • 閱讀代碼: 無論偏好哪種風格,都需要能夠熟練閱讀和理解這兩種風格的代碼,因為不可避免地會遇到使用不同風格的代碼庫。

五、 結(jié)論

  • 東 Const 與 西 Const 是兩種表達 const 限定符位置的風格,功能等價,各有優(yōu)劣。西 Const 更常見,東 Const 規(guī)則更統(tǒng)一。
  • 理解 頂層 Const(修飾對象本身)與 底層 Const(修飾指針/引用指向的內(nèi)容)是掌握 const 用法的關(guān)鍵,它決定了 const 在拷貝、賦值、函數(shù)重載和模板推導(dǎo)中的行為。
  • 無論選擇哪種風格,保持一致性是提高代碼質(zhì)量的黃金法則。
責任編輯:趙寧寧 來源: CppPlayer
相關(guān)推薦

2025-04-11 07:46:09

2022-04-02 10:52:33

Go開發(fā)面試

2025-03-10 07:05:07

2021-09-28 13:42:55

Chrome Devwebsocket網(wǎng)絡(luò)協(xié)議

2020-04-03 14:05:10

面試RedisJava

2024-04-22 00:00:00

CASCPU硬件

2021-07-28 10:08:19

類加載代碼塊面試

2023-09-12 14:56:13

MyBatis緩存機制

2019-04-19 12:46:18

面試丁校招簡歷

2012-02-15 13:03:40

網(wǎng)秦4C戰(zhàn)略

2022-06-07 12:03:33

Java內(nèi)存模型

2023-02-18 13:34:14

Nacos健康檢查機制

2022-06-06 15:33:20

線程Java釋放鎖

2019-12-30 14:34:33

NumpyPython數(shù)據(jù)科學

2013-10-17 09:58:48

2022-05-11 22:15:51

云計算云平臺

2023-12-29 13:45:00

2024-01-29 10:08:11

零拷貝Zero-copyCPU 拷貝

2024-02-21 16:42:00

2024-02-27 15:23:48

RedLock算法Redis
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 欧美精品福利 | 欧美久久久久久久久中文字幕 | 亚洲不卡在线视频 | 午夜精品久久久久久久99黑人 | 国产美女精品 | 一区二区三区在线 | 91精品国产麻豆 | 99精品免费在线观看 | 一区二区精品 | 精品丝袜在线 | 日韩欧美一区二区在线播放 | 黄色国产| 9999在线视频 | 综合久久久久久久 | 亚洲欧美激情精品一区二区 | 老牛嫩草一区二区三区av | 黄色大全免费看 | 国产一区二区三区免费 | 国产高清在线精品 | 天色综合网| 成人做爰9片免费看网站 | 日本电影免费完整观看 | 国产成人久久精品一区二区三区 | 中文字幕一区二区三区在线视频 | 日韩在线免费视频 | 免费观看成人鲁鲁鲁鲁鲁视频 | 久久69精品久久久久久久电影好 | www.国产 | 中文字幕一页二页 | 国产在线不卡 | 精品国产91乱码一区二区三区 | 成人免费视频观看视频 | 久久久精品国产 | 欧美一区成人 | 视频一区二区在线观看 | 99在线免费观看视频 | 男女网站免费 | 久久y| 毛片免费看 | 欧美日韩在线一区 | 欧美理论片在线 |