samedi 4 décembre 2021

Is dynamic_cast a bad practice in this context?

So I have been looking at numerous dynamic_cast questions, and it is generally considered a bad practice. I am not sure if using it is a good choice for my code.

So I want to implement matrix multiplication, for both dense and sparse matrices. Here is the base class:

class Matrix{
    protected:
    uint cols, rows;

    public:
    Matrix(uint rows, uint cols) : rows(rows), cols(cols){};

    virtual std::unique_ptr<Matrix> operator * (const Matrix & rhs);
    
    virtual void setValue(uint row, uint col, double value) = 0;
    virtual double getValue(uint row, uint col) const = 0;

    uint getCols() const {return cols;}
    uint getRows() const {return rows;}
};

I then define a dense matrix class, which is unimportant here, and define dense multiplication as the standard multiplication algorithm.

std::unique_ptr<Matrix> Matrix::operator*(const Matrix & rhs){
    std::unique_ptr<Matrix> result(new DenseMatrix(getRows(), rhs.getCols()));

    for(uint i = 0; i < rows; i++){
        for(uint k = 0; k < rhs.getRows(); k++){
            for(uint j = 0; j < rhs.getCols(); j++){
                result->setValue(i, j, result->getValue(i, j)+getValue(i, k)*rhs.getValue(k, j));                    
            }
        }
    }

    return result;
}

Now, I want to implement a coordinate sparse matrix, and make it so multiplication of two coordinate matrices is a different algorithm, since it can be done way faster. Here is the idea:

class ColCoordinateMatrix : public Matrix{
    //unimportant boilerplate code

    std::unique_ptr<Matrix> operator * (const Matrix & rhs) const override{
        const ColCoordinateMatrix * colRepresentation;
        if(colRepresentation = dynamic_cast<const ColCoordinateMatrix*>(&rhs)){
            //implement and return a much faster multiplication for sparse matrices here
            //return ...;
        }
        return Matrix::operator*(rhs);
    }
}

Now I am wondering - dynamic_cast is a bad practice, but I see no other way to resolve this problem. Is it really that bad here?

Aucun commentaire:

Enregistrer un commentaire