C ++运算符重载<<错误。 SafeMatrix 2D阵列

时间:2015-06-06 12:45:47

标签: c++ arrays templates pointers operator-overloading

我遇到运行此代码的问题。它应该是带有构造函数,析构函数,复制构造函数和运算符重载的模板化2D数组。

我的主要问题是导致错误的ostream& operator<<(ostream& os, SafeMatrix<class T> s)重载版。主要是,当我cout<<b[0][0]时,它打印得很好,但当我在ostream& operator<<(ostream& os, SafeMatrix<class T> s)上传器中执行时,我会收到错误。我正在尝试打印像cout << b这样的对象,正如您在main中看到的那样。

可能存在很多编码错误。对不起,我是模板和重载的新手。我一直在阅读和阅读,找不到与我的项目相关的任何内容。

#include <iostream>
#include <cstdlib>
#include <cassert>

using namespace std;
template <class T> class SafeMatrix{
private:
    int row_low, row_high, col_low, col_high;
    T** p;
public:

    // default constructor
    // allows for writing things like SafeMatrix a;
    SafeMatrix() : row_low(0), row_high(-1)
        , col_low(0), col_high(-1), p(nullptr){ }


    // 1 parameter constructor
    // SafeMatrix (10);
    SafeMatrix(int dim){
        if (dim <= 0){
            cout << "constructor error in bounds definition" << endl;
            exit(1);
        }
        row_low = 0; row_high = dim - 1;
        col_low = 0; col_high = dim - 1;
        p = new T*[dim];
        for (int i = 0; i < dim; i++)
            p[i] = new T[dim];
    }


    // 2 parameter constructor lets us write
    // SafeMatrix (10,20);
    SafeMatrix(int row, int col){
        if (row <= 0 || col<=0){
            cout << "constructor error in bounds definition" << endl;
            exit(1);
        }
        row_low = 0; row_high = row - 1;
        col_low = 0; col_high = col - 1;
        p = new T*[row];
        for (int i = 0; i < row; i++)
            p[i] = new T[col];
    }


    // 2 parameter constructor lets us write
    // SafeMatrix (10,20);
    SafeMatrix(int row_low, int row_high, int col_low, int col_high){
        if ((row_high - row_low + 1) <= 0 || (col_high - col_low + 1) <= 0){
            cout << "constructor error in bounds definition" << endl;
            exit(1);
        }
        this.row_low = row_low; this.row_high = row_high - 1;
        this.col_low = col_low; this.col_high = col_high - 1;
        p = new T*[(col_high - col_low) + 1];
        for (int i = 0; i <= row_high-row_low; i++)
            p[i] = new T[(col_high - col_low) + 1];
    }


    // copy constructor for pass by value and
    // initialization
    SafeMatrix(const SafeMatrix &s){
        int row = (s.row_high - s.row_low) + 1,
            col = (s.col_high - s.col_low) + 1;
        p = new T*[row];
        for (int i = 0; i < row; i++)
            p[i] = new T[col];
        for (int i = 0; i < row; i++)
            for (int j = 0; j < col;j++)
                p[i][j] = s.p[i][j];
        row_low = s.row_low; row_high = s.row_high;
        col_low = s.col_low; col_high = s.col_high;
    }


    // destructor
    ~SafeMatrix(){
        for (int i = 0; i < (row_high - row_low) + 1; i++)
            delete[] p[i];
        delete[] p;
    }

    friend class Brackets;

    //overloaded [] lets us write
    //SafeMatrix x(10,20); x[15]= 100;
    class Brackets {
    private:
        T* p1;
    public:
        Brackets(T* p2) : p1(p2) { }

        T& operator[](int i) {
            /*if (i<col_low || i>col_high) {
                cout << "index " << i << " out of range" << endl;
                exit(1);
            }*/
            return p1[i];
        }
    };

    Brackets operator[](int i) {
        if (i<row_low || i>row_high) {
            cout << "index " << i << " out of range" << endl;
            system("pause");
            exit(1);
        }
        return Brackets(p[i]);
    }


    // overloaded assignment lets us assign
    // one SafeMatrix to another
    SafeMatrix& operator=(const SafeMatrix & s){
        if (this != &s){
            delete[] p;
            int row = (s.row_high - s.row_low) + 1,
                col = (s.col_high - s.col_low) + 1;
            p = new T*[row];
            for (int i = 0; i < col; i++)
                p[i] = new T[col];
            for (int i = 0; i < row; i++)
                for (int j = 0; j < col; j++)
                    p[i][j] = s.p[i][j];
            this.row_low = s.row_low; this.row_high = s.row_high;
            this.col_low = s.col_low; this.col_high = s.col_high;
        }
        return *this;
    }


    // overloads << so we can directly print SafeMatrix
    friend ostream& operator<<(ostream& os, const SafeMatrix<T> s);

};

ostream& operator<<(ostream& os, SafeMatrix<class T> s){
    int row = (s.row_high - s.row_low) + 1,
        col = (s.col_high - s.col_low) + 1;
    for (int i = 0; i < row; i++){
        for (int j = 0; j < col; j++){
        cout << *((s.p+i)+j) << " ";
        }
        cout << endl;
    }
    return os;
};

int main(){

    SafeMatrix<int> b(3, 5);
    b[2][0] = 3;
    cout << b[2][0] <<endl;
    int counter = 0;
    for (int i = 0; i<3; i++)
        for (int j = 0; j < 5; j++)
            b[i][j] = ++counter;
    cout << "printing b the first time" <<endl;
    cout << b << endl;
    cout << "printing using []" << endl;
    for (int i = 0; i < 3; i++){
        for (int j = 0; j < 5; j++){
            cout << b[i][j] << " ";
        }
        cout << endl;
    }
}

我得到的错误有点疯狂,但在这里它们是:

error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class SafeMatrix<int>)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@V?$SafeMatrix@H@@@Z) referenced in function _main    D:\OneDrive\VS\SafeMatrix\matrix.obj    SafeMatrix

error LNK1120: 1 unresolved externals   D:\OneDrive\VS\SafeMatrix\Debug\SafeMatrix.exe  1   1   SafeMatrix

和这个警告:

Warning 1   warning C4150: deletion of pointer to incomplete type 'T'; no destructor called d:\onedrive\vs\safematrix\matrix.cpp    82  1   SafeMatrix

不知道这些是什么意思。

2 个答案:

答案 0 :(得分:0)

重载的运算符声明必须是自己的模板声明:

template <class U>
ostream& operator<<(ostream& os, const SafeMatrix<U> s);

此外,类中的friend声明必须使用新的类型参数名称,如:

template <class U>
friend ostream& operator<<(ostream& os, const SafeMatrix<U> s);

它可能不会重用T类型参数。重载运算符的类型参数是另一个。

答案 1 :(得分:0)

我认为你很简单忘了添加模板来重载。我没有检查其余部分:

#include <iostream>
#include <cstdlib>
#include <cassert>

using namespace std;

template <typename T> class SafeMatrix{
private:
    int row_low, row_high, col_low, col_high;
    T** p;
public:

    // default constructor
    // allows for writing things like SafeMatrix a;
    SafeMatrix() : row_low(0), row_high(-1)
        , col_low(0), col_high(-1), p(nullptr){ }


    // 1 parameter constructor
    // SafeMatrix (10);
    SafeMatrix(int dim){
        if (dim <= 0){
            cout << "constructor error in bounds definition" << endl;
            exit(1);
        }
        row_low = 0; row_high = dim - 1;
        col_low = 0; col_high = dim - 1;
        p = new T*[dim];
        for (int i = 0; i < dim; i++)
            p[i] = new T[dim];
    }


    // 2 parameter constructor lets us write
    // SafeMatrix (10,20);
    SafeMatrix(int row, int col){
        if (row <= 0 || col <= 0){
            cout << "constructor error in bounds definition" << endl;
            exit(1);
        }
        row_low = 0; row_high = row - 1;
        col_low = 0; col_high = col - 1;
        p = new T*[row];
        for (int i = 0; i < row; i++)
            p[i] = new T[col];
    }


    // 2 parameter constructor lets us write
    // SafeMatrix (10,20);
    SafeMatrix(int row_low, int row_high, int col_low, int col_high){
        if ((row_high - row_low + 1) <= 0 || (col_high - col_low + 1) <= 0){
            cout << "constructor error in bounds definition" << endl;
            exit(1);
        }
        this.row_low = row_low; this.row_high = row_high - 1;
        this.col_low = col_low; this.col_high = col_high - 1;
        p = new T*[(col_high - col_low) + 1];
        for (int i = 0; i <= row_high - row_low; i++)
            p[i] = new T[(col_high - col_low) + 1];
    }


    // copy constructor for pass by value and
    // initialization
    SafeMatrix(const SafeMatrix &s){
        int row = (s.row_high - s.row_low) + 1,
            col = (s.col_high - s.col_low) + 1;
        p = new T*[row];
        for (int i = 0; i < row; i++)
            p[i] = new T[col];
        for (int i = 0; i < row; i++)
        for (int j = 0; j < col; j++)
            p[i][j] = s.p[i][j];
        row_low = s.row_low; row_high = s.row_high;
        col_low = s.col_low; col_high = s.col_high;
    }


    // destructor
    ~SafeMatrix(){
        for (int i = 0; i < (row_high - row_low) + 1; i++)
            delete[] p[i];
        delete[] p;
    }

    friend class Brackets;

    //overloaded [] lets us write
    //SafeMatrix x(10,20); x[15]= 100;
    class Brackets {
    private:
        T* p1;
    public:
        Brackets(T* p2) : p1(p2) { }

        T& operator[](int i) {
            /*if (i<col_low || i>col_high) {
            cout << "index " << i << " out of range" << endl;
            exit(1);
            }*/
            return p1[i];
        }
    };

    Brackets operator[](int i) {
        if (i<row_low || i>row_high) {
            cout << "index " << i << " out of range" << endl;
            system("pause");
            exit(1);
        }
        return Brackets(p[i]);
    }


    // overloaded assignment lets us assign
    // one SafeMatrix to another
    SafeMatrix& operator=(const SafeMatrix & s){
        if (this != &s){
            delete[] p;
            int row = (s.row_high - s.row_low) + 1,
                col = (s.col_high - s.col_low) + 1;
            p = new T*[row];
            for (int i = 0; i < col; i++)
                p[i] = new T[col];
            for (int i = 0; i < row; i++)
            for (int j = 0; j < col; j++)
                p[i][j] = s.p[i][j];
            this.row_low = s.row_low; this.row_high = s.row_high;
            this.col_low = s.col_low; this.col_high = s.col_high;
        }
        return *this;
    }


    // overloads << so we can directly print SafeMatrix
    template <typename T> friend ostream& operator<<(ostream& os, const SafeMatrix<T> s);

};

template <typename T>
ostream& operator<< (ostream& os, const SafeMatrix<T> s) {
    int row = (s.row_high - s.row_low) + 1,
        col = (s.col_high - s.col_low) + 1;
    for (int i = 0; i < row; i++){
        for (int j = 0; j < col; j++){
            os << *((s.p + i) + j) << " ";
        }
        os << endl;
    }
    return os;
}

int main(){
    SafeMatrix<int> a(10), b(3, 5);
    b[2][0] = 3;
    cout << b << endl;

    system("PAUSE");
    return 0;
}

此代码适用于十六进制打印...