理解c++中explicit關鍵字的作用
explicit 關鍵字的作用是防止構造函數被隱式調用,從而避免意外的類型轉換
#include <iostream>
class Vec3 {
public://構造函數沒有被explicit修飾Vec3(float value): x(value), y(value), z(value){}Vec3(float val1, float val2, float val3): x(val1), y(val2), z(val3){}void print() const {std::cout << "x: " << x << ", y: " << y << ", z: " << z << std::endl;}
private:float x, y, z;
};int main() {Vec3 v1(1.0f); //顯式調用單值構造函數v1.print();Vec3 v2 = 1.0f;//由于vec3構造函數沒有被explicit修飾,所以可以發生隱式調用,發生隱式轉換,float轉為vec3v2.print();Vec3 v2(1.0,2.0,3.0);//Vec3 v2 = (1.0, 2.0, 3.0);//這個是錯誤的v2.print();return 0;
}
如果構造函數沒有被explicit修飾,則允許發生隱式調用,而隱式調用會發生隱式轉換,即float轉換為自定義vec3
Vec3 v2 = 1.0f; //隱式調用構造函數,有點像賦值操作,使得讀代碼的人有點迷惑,可以在單參數構造函數前添加explicit禁用這種調用構造函數的方式
explicit 只能用于修飾單參數構造函數,不能用于普通成員函數或靜態函數
隱式轉換可能帶來以下不良影響:
意外行為:隱式轉換可能導致程序行為與預期不符,尤其是在類型不匹配或轉換規則復雜時。
性能問題:隱式轉換可能引入額外的開銷,例如創建臨時對象或調用額外的構造函數。
代碼可讀性降低:隱式轉換可能使代碼難以理解,開發者可能無法直觀地看出轉換發生的位置和原因。
類型安全性降低:隱式轉換可能導致類型安全問題,例如將一個類型錯誤地轉換為另一個類型,導致潛在的運行時錯誤。
調試困難:隱式轉換可能隱藏問題的根源,增加調試的復雜性。
為了防止隱式轉換帶來的不良影響,我們還是對單參數構造函數使用explicit修飾,防止隱式調用單參數構造函數
#include <iostream>class Vec3 {
public:// 使用 explicit 防止隱式轉換//構造函數explicit Vec3(float value) : x(value), y(value), z(value) {}void print() const {std::cout << "Vec3(" << x << ", " << y << ", " << z << ")" << std::endl;}private:float x, y, z;
};int main() {Vec3 v1(1.0f); // 正確:顯式調用構造函數v1.print();// Vec3 v2 = 1.0f; //隱式調用構造函數,錯誤:explicit 禁止隱式轉換// v2.print();return 0;
}
//禁用隱式調用單參數構造函數
Vec3 v2 = 1.0f //無法將浮點類型float轉換為類Vec3
//只允許顯式調用單參數構造函數
Vec3 v1(1.0f);
隱式調用單參數構造函數由于explicit修飾而被禁用