c++ - 使用 operator<< 并打印错误值的类的程序 c++

标签 c++ matrix operator-keyword

我做了一个矩阵类。这是它的一部分。

Math::Matrix::Matrix(int row, int col, double * mat)
{
    this->mat = new double[(this->row = row) * (this->col = col)];
    for (int i = 0; i < row * col; i++)
    {
        this->mat[i] = mat[i];
    }
}


Math::Matrix::~Matrix()
{
    if (this->mat != nullptr)
    {
        delete[] this->mat;
    }
}

const Math::Matrix Math::Matrix::multiply(Matrix & A) const
{
    if (!this->is_multipliable(A))
    {
        throw new std::exception("Math::Matrix::multiply : cannot multiply!");
    }
    Matrix B = Matrix(this->row, A.col);
    for (int k = 0; k < this->col; k++)
    {
        for (int i = 0; i < this->row; i++)
        {
            for (int j = 0; j < A.col; j++)
            {
                B.mat[i * A.col + j] = this->mat[i * this->col + k] * A.mat[k * A.col + j];
            }
        }
    }
    return B;
}

std::ostream & Math::operator<<(std::ostream & os, const Matrix & m)
{
    for (int i = 0; i < m.row; i++)
    {
        for (int j = 0; j < m.col; j++)
        {
            os << m.mat[i*m.col + j] << ' ';
        }
        os << '\n';
    }
    return os;
}

这是我写的矩阵类的一部分,当我尝试的时候

int main()
{
    A = Math::Matrix(2, 3, new double[6]{ 1, 2, 3, 4, 5, 6 });
    B = Math::Matrix(3, 4, new double[12]{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2 });
    std::cout << A << std::endl;
    std::cout << B << std::endl;
    std::cout << A.multiply(B) << std::endl;
}

在main中,程序会输出一些愚蠢的数字,比如

-1.45682e+144 -1.45682e+144 -1.45682e+144

-1.45682e+144 -1.45682e+144 -1.45682e+144


-1.45682e+144 1.07458e-255 3.02386e-294 1.41763e-311

2.122e-314 -7.84591e+298 -1.45684e+144 1.87482e-310

2.9803e-294 -1.45682e+144 -1.45682e+144 -1.45682e+144


-1.45682e+144 -1.45682e+144 -1.45682e+144 -1.45682e+144

-1.45682e+144 -1.45682e+144 -1.45682e+144 -1.45682e+144

(不调试)

1 2 3

4 5 6


-1.45682e+144 -1.45682e+144 -1.45682e+144 -1.45682e+144

-1.45682e+144 -1.45682e+144 -1.45682e+144 -1.45682e+144

3.67842e-293 8.81477e-310 3.6647e-293 -1.45682e+144


-1.45682e+144 -1.45682e+144 -1.45682e+144 -1.45682e+144

-1.45682e+144 -1.45682e+144 -1.45682e+144 -1.45682e+144

(调试)

然后抛出异常。

在 Debug模式下,它表示“wntdll.pdb 包含查找模块 ntdll.dll 源代码所需的调试信息”。

我使用的是 visual studio 2017。

这段代码似乎有什么问题?

最佳答案

让我们猜测一下您是如何定义 Matrix 的,然后将其重写为默认情况下正确

namespace Math {

class Matrix {
    double * mat; // Bad. Owning raw pointer
    int col, row; // Questionable. std::size_t is the normal type for an index
public:
    Matrix(int row, int col, double * mat); // Bad. Owning raw pointer
    ~Matrix(); // Will be un-necessary under the rule of 0
    const Matrix multiply(Matrix & A) const; // this is usually named "operator *"
    friend std::ostream & operator<<(std::ostream & os, const Matrix & m); // Good
};
}

这是我们整理的方式

namespace Math {

class Matrix {
    std::vector<double> mat; 
    std::size_t col, row; 

public:
    Matrix(std::size_t row, std::size_t col) 
     : row(row), col(col), mat(row * col, 0) 
    {}

    template <typename InputIterator>
    Matrix(std::size_t row, std::size_t col, InputIterator it) // copy from any sequence of doubles
     : Matrix(row, col) // delegate to 2-arg constructor to initialises fields
    {
        std::copy_n(it, row * col, mat.begin());
    }

    double & data(std::size_t c, std::size_t r) // Convinience
    { return mat[(r * col) + c]; }

    double data(std::size_t c, std::size_t r) const // Overload for const
    { return mat[(r * col) + c]; }

    friend Matrix operator*(const Matrix & lhs, const Matrix & rhs)
    {
        if (!lhs.is_multipliable(rhs))
        {
            // MSVC includes this as a non-standard extension
            // std::runtime_error is a portable replacement
            throw new std::exception("Math::Matrix::multiply : cannot multiply!");
        }
        Matrix result = Matrix(lhs.row, rhs.col);
        for (int k = 0; k < lhs.col; k++)
        {
            for (int i = 0; i < lhs.row; i++)
            {
                for (int j = 0; j < rhs.col; j++)
                {
                    result.data(i, j) += lhs.data(i, k) * rhs.data(k, j);
                }
            }
        }
        return result;
    }

    friend std::ostream & operator<<(std::ostream & os, const Matrix & m);    
    friend std::istream & operator>>(std::istream & is,       Matrix & m);    
};
}

请注意,std::exception 未定义为具有 const char * accepting constructor

关于c++ - 使用 operator<< 并打印错误值的类的程序 c++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50412616/

相关文章:

c++ - 检查指向 vector C++中对象的指针

c# - 从 C# 调用 C++ 时出现 System.AccessViolationException

c++ - 我如何使用 GetAdaptersAddresses() 发送 ip 地址

python - 在 Python 中,根据自定义比较过滤短列表以仅包含唯一值的巧妙方法是什么?

c++ - 如何在需要时互换不同的运算符(operator)?

c++ - 当我需要知道最大值和谁达到最大值时使用什么容器?

c++ - 将(C 类)指针转换为 C++ 矩阵

java - 标准化 vector ,使所有元素之和每次都加到 1

python - numpy:在二维数组中找到对称值

fortran - 运算符(operator)检查文件是否存在