常見易錯問題

2021-05-23 03:27:04 字數 4110 閱讀 6566

型別轉換

一、const_cast

去除常量特性

二、static_cast

普通型別轉換和類繼承的父指標到子類指標的轉換

(引用一樣)

注意:不能用於物件本身,只轉換不進行執行時型別檢查

不能進行的轉換:1、

*p -- > int 2

、aobj ---> bobj 3

、const --> non-const

總的來說,沒有意義的轉化,該轉換都不能做到

三、reinterpret_cast

轉換型別:

1、無關的指標到指標

(型別在繼承層次中不相關也可以)

2、無關的引用到引用

(型別無關)

例如:class x{};

class y{};

x x;

y y;

x* px;

y* py;

px = reinterpret_cast(py);

py = reinterpret_cast(px);

y& ry = y;

x& rx = reinterpret_cast(ry); 3

、指標到

int 4、

int到指標

5、函式指標

注意:此型別也不會進行型別檢查

四、dynamic_cast

繼承層次的指標,引用進行轉換。執行時進行底層物件型別檢查。

注意:由於執行時型別資訊存在物件的

vtable

中,因此類中必須有乙個虛函式。 引用

1、必須在建立時初始化

2、引用指向乙個

const

值,就可以建立未命名值的引用,否則編譯錯誤

例如:const int& ref = 5; //

正確int& ref = 5; //

錯誤3、

引用的修改誤區

(引用指向不可更改)

引用一旦建立它的指向就不能在修改,可以改變它的值

(即指向的變數的值)。

例如:int a = 10, b = 20;

int & ra = a;

cout << ra << endl;

cout << a << endl;

ra = b; //

改變只是

ra的值也就是

a的值,並不會改變指向

cout << ra << endl;

cout << a << endl;

當你寫出如下**來繞過這條限制時:

ra = &b; //

錯誤//

表示式的兩側的型別不匹配。右側

&b是乙個指標,左側是

int變數的引用,而不是指標的引用。

當引用給引用又會如何:

int &rb = b;

ra = rb; //

依然是賦值操作,而不會改變

ra指向。

4、指標的引用,引用的指標,引用的引用:

指標的引用宣告方式:型別

+*+&+refname = pointname

例如:int* pint = &a;

int* &rpint = pint;

cout << *rpint <

int& *pra = ra; //

不能宣告引用的指標

int& &rra = ra; //

不能宣告引用的引用

5、取引用的位址和取引用所指變數的位址是一樣的;

例如:cout << &ra cout << &a 6、引用資料成員

當資料成員是引用時必須依靠成員初始化列表完成,不能通過建構函式體中完成。這樣的原因是:如果引用不指向其他變數就無法存在。

例如:class x

private:

const int # };

7、引用引數

當函式引數為引用引數時,對被呼叫函式的引數修改就會修改外部呼叫**的實參。因為可以把這種現象看成是實參的別名,就像上述引用的討論一樣。引用引數提高了程式的效率,因為減少了拷貝構造的呼叫操作。

引用引數帶來的好處:

1、效率:當複製大物件時花費很長時間,傳遞物件或指標會節省時間。

2、正確性:不是所有的物件都允許傳值,即使傳值,也不一定就能正確的完成深拷貝操作。支援此操作,動態分配的物件必須提供定製的拷貝構造。

運用時機:對於內建型別,不需要修改實參,就應使用傳值方式。其他都可以使用引用。

8、引用返回值

當返回值是引用時,引用所對應的變數即將銷毀,它所指向的資料將會出現問題,因為變數的生命週期已經結束。

運用時機:

1、當返回值是引用時,一般是出於效率的考慮,這樣可以避免不必要的複製操作,只有當前物件在函式結束後依然存在的情況下。

2、為了實現鏈式操作

9、與指標的比較:

1、使程式清晰明了

2、**安全

(不存在無效的引用)

準則:除非動態分配或在其他改變或釋放指標指向的值,否則都應使用引用而不是指標

const

應用事項

const

修飾變數

(必須初始化)

1、定義常量

例如:const int arraysize = 10; 2

、指標常量,常量指標

當const

和型別同在

*的左側時:

(常量指標)

如:const +

型別+ * + point 或型別

+ const + * + point

指標指向可以改,指標指向的值是不能通過指標進行修改。

當const

緊靠變數的左側時:

(指標常量)

指標指向不可改,指標指向的值是可以通過指標進行修改。3、

const

引用int a = 50;

const int& ra = a; //const int&

等價int const&

ra = 4; //

不能通過引用修改

a,可以直接修改a;

a = 100;

cout << ra <

總結:修飾的目標在於

const 在*

的左邊,還是右邊。

左邊修飾的是指標的內容,右邊修飾的是指標的指向

const

修飾函式

const

物件只能呼叫

const

成員函式

非const

物件都兩者都可呼叫

const

成員函式只能呼叫

const

成員函式

const

修飾引數

防止引數被修改

(代表輸入引數)

const

引用作引數,既提高效率,有防止修改實參

const

修飾返回值

static

使用static

內部連線符

(匿名命名空間也可達到此效果

)只在宣告它的當前編譯單元可以使用

const

,typedef

預設都是內部連線

extern

外部連線符

多個編譯單元都可使用

const

,typedef

預設都是內部連線,可以是

extern

指定外部連線。

把乙個名字指定為外不連線時,編譯器把它當作宣告來對待。所以編譯器不會分配空間,因此,必須提供另外的定義。

static變數(

記憶性變數)

函式中的

static

變數,只初始化一次,下次用上次的值。

類中的static變數(

準側:採用物件內維護變數的狀態)

與類關聯而不是與類物件關聯,物件擁有的是副本

static

初始化在

mian

前執行,

預設初始化零值,類中的也是一樣。

準側:不同原始檔中非區域性變數初始化順序不確定。

static

函式沒有

this

指標只能訪問靜態成員

巢狀呼叫易錯問題

general.h內容如下 pragma once include h1.h include struct tt 再建乙個h1.h 檔案,內容如下 include general.h using namespace std void print tt t main.cpp裡面呼叫 print 函式,...

C C 易錯問題分析

傳給函式形參的實參是作為拷貝傳入,在函式體內改變作為拷貝的實參2是不會影響到傳入的實參1的。規則 1 如果想要通過函式介面改變傳入的數值,那麼需要傳入該數值的指標。2 如果想要改變傳入的指標所指向的值,那麼需要傳入該指標的指標。總之,需要深一層。int fun int fun1 修改方法 由上層呼叫...

細節問題 易錯問題 zz錯誤

一 關於精度的問題 float精度是2 23,能保證6位。double精度是2 52,能保證15位。但是預設float和double都只能顯示6位,再多需要 include 然後在輸出語句之前插入cout setprecision 20 強制輸出小數字。float fval 1.32121212f ...