2017-07-15 72 views
3

嘿,我試圖瞭解指針和參考安全使用中的區別是什麼,很多人說參考比指針更安全,它不能爲空。但對於下面的代碼也顯示,參考可以創建運行時錯誤,但不是指針:爲什麼參考比指針更安全?

class A { 
public: 
    A(): mAi(0) {} 
    void ff() {std::cout << "This is A" << std::endl;} 
    int mAi; 
}; 

class B { 
public: 
    B() : mBi(0), mAp(NULL) {} 
    A* getA() const { return mAp; } 
    void ff(){std::cout << "This is B" << std::endl;} 
    int mBi; 
    A* mAp; 
}; 

int main() 
{ 
    B* b = new B(); 
    /// Reference part 
    A& rA = *b->getA(); 
    rA.ff(); 
    std::cout << rA.mAi << std::endl; 
    /// Pointer part 
    A* pA = b->getA(); 
    if (NULL != pA) 
    { 
     pA->ff(); 
     std::cout << pA->mAi << std::endl; 
    } 
} 

該代碼會崩潰的「參考部分」而不是「指針的一部分」。 我的問題是:

  1. 爲什麼我們總是說,參考比指針安全,如果他們可能是無效的(如前面的代碼),我們無法檢查其無效?

  2. 使用指針或引用之間在RAM或CPU消耗方面有什麼區別? (是否值得重構大碼時,我們就可以使用引用,而不是指針?)

回答

3

引用不能被NULL,這是正確的。你的代碼的參考部分。然而崩潰,因爲你明確地試圖取消引用當您嘗試初始化參考NULL指針,不能因爲參考是有史以來null

*b->getA(); // Equivalent to *((A*) NULL) 

引用可以成爲懸空引用不過,如果你不喜歡的東西:

int* a = new int(5); 
int& b = *a; 

// Some time later 
delete a; 

int c = b + 2; // Ack! Dangling reference 

的指針就不會你在這裏保存,這裏是一個使用指針的等效代碼:

int* a = new int(5); 
int* b = a; 

// Some time later 
delete a; 

if(b) { // b is still set to whatever memory a pointed to! 
    int c = *b + 2; // Ack! Pointer used after delete! 
} 

指針和引用不可能產生任何性能差異,它們可能類似地在引擎蓋下實現,具體取決於您的編譯器。如果編譯器可以精確地確定引用綁定的內容,那麼引用可能會被完全優化。