2017-07-15 73 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! 
} 

指针和引用不可能产生任何性能差异,它们可能类似地在引擎盖下实现,具体取决于您的编译器。如果编译器可以精确地确定引用绑定的内容,那么引用可能会被完全优化。