2015-09-10 106 views
-2

我認爲朋友功能可以訪問所有會員。即使在這個問題上,它的工作:
C++ friend function can't access private members朋友功能不允許訪問私人會員

在這個問題給出的答案似乎等同於我的代碼,他編細而我只是說array_是pivate。有人知道爲什麼

.H:

#ifndef matrix_h 
#define matrix_h 

#include <iostream> 
using namespace std; 

template <typename Comparable> 
class matrix 
{ 
    private: 
     size_t num_cols_; 
     size_t num_rows_; 
     Comparable **array_; 

    public: 
     friend ostream& operator<< (ostream& o, const matrix<Comparable> & rhs); 
     size_t NumRows(); 
     size_t NumCols(); 
}; 
#endif 

的.cpp:

#include <iostream> 
#include "matrix.h" 

using namespace std; 

template <typename Comparable> 
ostream& operator<< (ostream& o, matrix<Comparable> & rhs){ 
    size_t c = rhs.NumRows(); 
    size_t d = rhs.NumCols(); 
    for (int i = 0; i < c; i++){ 
     for (int j = 0; j < d; j++){ 
      o << rhs.array_[i][j];   //not allowed 
     } 
     o << endl; 
    } 
    return o; 
} 

template <typename Comparable> 
size_t matrix<Comparable>::NumRows(){ 
    return num_rows_; 
} 

template <typename Comparable> 
size_t matrix<Comparable>::NumCols(){ 
    return num_cols_; 
} 


int main(){ 
    matrix<int> a; 
    cout << a << endl; 

} 
+0

聲明瞭友元函數採取'常量矩陣&',但其定義中的一個'矩陣&'。它們不是同一個功能。 – user657267

+1

另請參見:[爲什麼模板只能在頭文件中實現?](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – NathanOliver

+0

如果我讓它們都是const,或者刪除const,那麼我會得到一個未定義的引用錯誤。未定義對運營商的引用<< – user3444650

回答

0

說你在這兩個地方使用const並添加constnumRowsnumCols過的聲明。那麼問題是什麼?那麼...

你認爲它是相同的,但你的代碼有一個模板。和朋友聲明

friend ostream& operator<< (ostream& o, const matrix<Comparable> & rhs); 

不是一個模板,所以它不匹配的定義

template <typename Comparable> 
ostream& operator<< (ostream& o, matrix<Comparable> & rhs){ // ... 

模板。事實上GCC會給出警告:

matrix.h:16:79: warning: friend declaration ‘std::ostream& operator<<(std::ostream&, const matrix<Comparable>&)’ declares a non-template function [-Wnon-template-friend] 
     friend ostream& operator<< (ostream& o, const matrix<Comparable> & rhs); 
                      ^
matrix.h:16:79: note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) 

人們很容易只是朋友所有專業,像這樣:

template <typename T> 
friend ostream& operator<< (ostream& o, const matrix<T> & rhs); 

不幸的是,這不會爲工作原因這裏解釋:Why can templates only be implemented in the header file?你能夠編譯matrix.cpp,但不是一個單獨的驅動程序,這樣的:

#include <iostream> 
#include "matrix.h" 
using namespace std; 
int main() { 
    matrix<int> m; 
    cout << m << endl; 
} 

你得到一個未定義的引用錯誤。相反,你應該只在頭文件中定義整個矩陣類,然後將.cpp文件丟棄。

需要指出的是,這仍然存在一個問題:您可以稱此爲operator<<就好,但您不能說它的地址,因爲它只能通過依賴於參數的查找找到。

auto ptr = static_cast<ostream&(*)(ostream&, const matrix<int>&)>(operator<<); // error 

對於通過非限定查找找到它,它必須在名稱空間範圍內具有匹配聲明。而寫這樣一個聲明實際上是不可能的(C++的語法沒有辦法做到這一點)!爲了解決這個問題,我們需要把operator<<成函數模板,定義在線:

template <typename Comparable> 
class matrix { 
    // ... 
    template <typename T> 
    friend ostream& operator<<(ostream& o, const matrix<T>& rhs) { 
     // ... 
    } 
    // ... 
}; 
// namespace-scope declaration 
template <typename T> 
ostream& operator<<(ostream& o, const matrix<T>& rhs); 

現在上面的代碼以運營商的地址將工作。

0
  1. 編譯器抱怨是因爲你實現的函數與你聲明的函數不同(在聲明中rhs是由const裝飾的,在實現中它不是)。
  2. 在實現中添加const之後,編譯器會抱怨「未定義的引用」,因爲聲明和實現仍然不相同。實現是一個模板函數,decalartion不是。

    #ifndef matrix_h 
    #define matrix_h 
    
    #include <iostream> 
    using namespace std; 
    
    template <typename Comparable> 
    class matrix 
    { 
        private: 
         size_t num_cols_; 
         size_t num_rows_; 
         Comparable **array_; 
    
        public: 
         template<typename T> 
         friend ostream& operator<< (ostream& o, const matrix<T> & rhs); 
         size_t NumRows() const; 
         size_t NumCols() const; 
    }; 
    
    template <typename Comparable> 
    ostream& operator<< (ostream& o, const matrix<Comparable> & rhs){ 
        size_t c = rhs.NumRows(); 
        size_t d = rhs.NumCols(); 
        for (int i = 0; i < c; i++){ 
         for (int j = 0; j < d; j++){ 
          o << rhs.array_[i][j];   //not allowed 
         } 
         o << endl; 
        } 
        return o; 
    } 
    
    template <typename Comparable> 
    size_t matrix<Comparable>::NumRows() const{ 
        return num_rows_; 
    } 
    
    template <typename Comparable> 
    size_t matrix<Comparable>::NumCols() const{ 
        return num_cols_; 
    } 
    
    #endif