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

Posted

技术标签:

【中文标题】在基类对象内部创建派生类对象【英文标题】:Creating a derived class object inside of base class object 【发布时间】:2014-09-02 13:09:06 【问题描述】:

我正在根据策略模式实施矩阵。 为此,我有 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 对象的多态行为,因为没有 Matrix 对象。 在 Matrix 方法中创建 Matrix 派生对象没有任何问题。没有其他方法可以从中返回 Matrix 对象。您不愿意使用工厂模式似乎没有根据。 【参考方案1】:

如果要根据条件创建不同类型的对象,则必须使用工厂。如果您不想让Matrix 知道它的后代,您有多种选择。除了implementations using interfaces,在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);

【讨论】:

以上是关于在基类对象内部创建派生类对象的主要内容,如果未能解决你的问题,请参考以下文章

将派生类对象存储在基类变量中

将派生类对象存储在基类变量中

在基类类型的向量中保存的基对象和派生对象被切片

在基类中存储指向派生类函数的指针

在基类和派生类中使用基类的装饰器

基类 派生类 类的继承与约束