在基类对象内部创建派生类对象

Creating a derived class object inside of base class object

本文关键字:对象 派生 创建 内部 基类      更新时间:2023-10-16

我正在根据策略模式实现矩阵。为此,我有MyMatrix,它保存了一个指向Matrix的指针,还有两个继承自Matrix的子类——SparseMatrix&RegMatrix。当添加两个矩阵时,因为我不知道我要将哪个矩阵添加到哪个矩阵,所以我实现了一个基函数,该函数使用每个继承类的内部方法,当添加时,我只将新元素添加到左侧矩阵中。

这很好用。

我的问题是——我现在想做矩阵乘法。我想在基类Matrix中实现这个方法。这就是我现在所拥有的:

Matrix& multiple(Matrix &other)
{
    double result = 0;
    int newMatrixRowSize = getRowSize();
    int newMatrixColSize = other.getColSize();
    double *resultArray = new double[newMatrixRowSize*newMatrixColSize];
    for (int i = 1; i <= getColSize(); i++)
    {
        for (int j = 1; j <= other.getColSize(); j++)
        {
            for (int k = 1; k <= other.getRowSize(); k++)
            {
                Pair firstPair(i,k);
                Pair secondPair(k,j);
                result += getValue(firstPair)*other.getValue(secondPair);
            }
            Pair resultIndex(i,j);
            resultArray[getNumIndex(resultIndex, newMatrixRowSize, newMatrixColSize)] = result;
            result = 0;
        }
    }
    delete [] resultArray;
}

唯一的问题是,现在我不能只把新元素添加到左手矩阵中,我必须创建一个新的RegMatrix或SparseMatrix,并根据矩阵中的零的数量交换到矩阵的合法表示。

所以我的问题是,在基类中创建基类派生类的实例是"合法的"还是良好的做法?我想避免使用工厂模式,更愿意在不知道手中矩阵类型的情况下做多态的事情

如果您想根据条件创建不同类型的对象,则必须使用工厂。如果您不想让Matrix知道它的后代,您有几个选项。除了使用接口的实现之外,在C++11中,您还可以使用std::function:

class Matrix {
     typedef std::function<Matrix*(const double*, int, int)> Factory;
     Factory factory;
public:
     Matrix(const Factory& f) : factory(f) {}
     Matrix* multiple(Matrix &other) {
         ....
         return factory(resultArray, newMatrixRowSize, newMatrixColSize);
     }
};

它给你的优势是,你可以像工厂一样传递任何类似函数的对象:

Matrix* matrixFactoryFunc(const double* data, int rowSize, int colSize) {
    return nullptr;
}
class MatrixFactoryCallable {
public:
    Matrix* operator()(const double* data, int rowSize, int colSize) {
        return nullptr;
    }
};
class MatrixFactoryWithMemFun {
public:
    Matrix* createMatrix(const double* data, int rowSize, int colSize) {
    }
};
void testFactory() {
    std::function<Matrix*(const double*, int, int)> factory;
    factory = matrixFactoryFunc;
    factory = MatrixFactoryCallable();
    MatrixFactoryWithMemFun mi;
    factory = std::bind(&MatrixFactoryWithMemFun::createMatrix, &mi, _1, _2, _3);
    Matrix m(factory);
}