2012-08-29 53 views
1

考慮下面的代碼:引用無效初始化:指針和值之間的區別?

#include <iostream> 
#include <vector> 

template<typename Type> class MyClass 
{ 
    public: 
     MyClass(Type* ptr) : _ptr{ptr}, _val{*ptr} {;} 
     inline Type*& getptr() {return _ptr;} 
     inline Type*& getptrc() const {return _ptr;} 
     inline Type& getval() {return _val;} 
     inline Type& getvalc() const {return _val;} 
    protected: 
     Type* _ptr; 
     Type _val; 
}; 

int main() 
{ 
    std::vector<double> v = {0, 1, 2}; 
    MyClass<const double> x(&v[0]); 
    x.getval(); 
    x.getvalc(); // <- OK 
    x.getptr(); 
    x.getptrc(); // <- ERROR : "invalid initialization of reference of type 'const double*&' from expression of type 'const double* const'" 
    return 0; 
} 

GCC產生用於getptrc功能invalid initialization of reference of type 'const double*&' from expression of type 'const double* const'錯誤。但函數getvalc編譯得很好。我不明白getvalc和getptrc之間的區別是錯誤的起源。

錯誤的原因是什麼,爲什麼我不能把一個const函數返回一個指針的引用?

+0

如果您需要參考,下面是編譯的代碼:http://liveworkspace.org/code/8eb059d7b1869316740a6e620ebf5ad2。當然,對速度指針的引用不會有太大的作用,如果你需要修改它,'const'不是正確的選擇。 – chris

回答

5

const double*&是對指向const double的指針的引用。

const double* constconst指向const double的指針。

這意味着你必須返回一個常數指針

inline Type* const & getptrc() const {return _ptr;} 

const上的方法意味着你不會修改數據成員。要滿足該合同,您必須返回一個常數指針,否則您可以修改數據成員_ptr。但是,在getvalc的另一個案例中,您已通過返回const double填滿了該合同。

+0

哦,我討厭C++及其語法特性。 –

1

MyClass<const double>中,名稱Type是指const double。因此,返回Type&的成員函數getvalc()很好:它返回const double&,並且_val不能通過該引用進行修改。

Type*&還有另一層間接尋址;儘管Typeconst double,指向它的指針是可修改的;這就是編譯器抱怨的原因:_ptr在const成員函數中是const,但函數試圖將其作爲可修改的指針返回。