C++ 不允许朋友函数访问私人成员

C++ 不允许朋友函数访问私人成员,c++,operator-overloading,friend,C++,Operator Overloading,Friend,我以为朋友功能可以访问所有成员。即使在这个问题上,它也起了作用: 这个问题给出的答案似乎与我的代码相同,他的编译很好,而我的只是说array_uuu是pivate。有人知道为什么吗 .h: #ifndef矩阵 #定义矩阵 #包括 使用名称空间std; 模板 类矩阵 { 私人: 大小\u t数量\u列\u; 大小\u t数量\u行\u; 可比**数组u2;; 公众: friend ostream&operator说您在这两个地方都使用了const,并将const添加到numRows和numCol

我以为朋友功能可以访问所有成员。即使在这个问题上,它也起了作用:

这个问题给出的答案似乎与我的代码相同,他的编译很好,而我的只是说array_uuu是pivate。有人知道为什么吗

.h:

#ifndef矩阵
#定义矩阵
#包括
使用名称空间std;
模板
类矩阵
{
私人:
大小\u t数量\u列\u;
大小\u t数量\u行\u;
可比**数组u2;;
公众:

friend ostream&operator说您在这两个地方都使用了
const
,并将
const
添加到
numRows
numCols
的声明中。那么问题出在哪里呢

您认为它是相同的,但是您的代码有一个模板。还有朋友声明

friend ostream& operator<< (ostream& o, const matrix<Comparable> & rhs);
您会得到一个未定义的引用错误。相反,您实际上应该在头文件中定义整个矩阵类,并放弃.cpp文件

应该指出的是,这仍然有一个问题:您可以调用这个
操作符
  • 编译器会抱怨,因为您实现的函数与您声明的函数不同(在声明中rhs由const修饰,在实现中则不是)
  • 在实现中添加常量后,编译器会抱怨“未定义引用”,因为声明和实现仍然不相同。实现是一个模板函数,而departion不是

    #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
    
    #ifndef矩阵
    #定义矩阵
    #包括
    使用名称空间std;
    模板
    类矩阵
    {
    私人:
    大小\u t数量\u列\u;
    大小\u t数量\u行\u;
    可比**数组u2;;
    公众:
    模板
    
    friend ostream&Operator您已声明friend函数采用
    常量矩阵&
    ,但其定义采用
    矩阵&
    。它们不是同一个函数。此外:如果我将它们都设为常量,或删除常量,则会出现未定义的引用错误。对运算符的未定义引用愤怒:冲突。您的矩阵将具有未定义的引用如果复制或移动,可能会导致致命的行为。我有一个构造函数/析构函数/复制重载。我只是没有包含它,因为它不相关。我也不应该使用.cpp吗?
    friend ostream& operator<< (ostream& o, const matrix<Comparable> & rhs);
    
    template <typename Comparable>
    ostream& operator<< (ostream& o, matrix<Comparable> & rhs){ // ...
    
    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);
    
    #include <iostream>
    #include "matrix.h"
    using namespace std;
    int main() {
        matrix<int> m;
        cout << m << endl;
    }
    
    auto ptr = static_cast<ostream&(*)(ostream&, const matrix<int>&)>(operator<<); // error
    
    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);
    
    #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