问题陈述:让Matrix
成为DenseMatrix
和SparseMatrix
(以及可能还有其他人)的子类。我想要实现的目标如下:
Matrix *A = new DenseMatrix();
Matrix *B = new SparseMatrix();
Matrix C = (*A) + (*B); // dense + sparse
Matrix D = (*A) + (*A); // dense + dense
Matrix E = (*B) + (*B); // sparse + sparse
更好的是,我想拥有以下内容:
DenseMatrix C = (*A) + (*B);
DenseMatrix D = (*A) + (*A);
SparseMatrix E = (*B) + (*B);
现在,当DenseMatrix
添加SparseMatrix
并同时声明为Matrix
时,operator+
意味着Matrix
中必须有AddEnabled<Foo>
定义。
我已经阅读了使用接口DenseMatrix
的{{3}},但在(几乎)任何可能的加数组合时似乎不是一个好的解决方案。我可以在friend DenseMatrix operator+ (DenseMatrix const& left, DenseMatrix const& right);
中定义以下函数:
DenseMatrix
但是,再次无法添加两个Matrix
声明为Matrix *A = new DenseMatrix();
的实例(即opeator+
)。
从各种类似的问题和答案我怀疑 pimpl成语可能是相关的,但我不知道如何。
注意:我在C ++ 98编码,而不是C ++ 11。
更新:正如DieterLücking在答案中建议的那样,需要在基类中引入Matrix
。这是有道理的,但问题是Matrix
是抽象的,不允许返回抽象类型的方法。但是,可以返回指针或Matrix& operator+(const Matrix& right) const;
的引用;这样我们就会得到一个定义:
+
在某种程度上这可行,但我的代码的用户希望Matrix
返回function [J, grad] = costFunction(theta, X, y)
m = length(y); % number of training examples
S = 0;
J = 0;
for i=1:m
Yi = y(i);
Xi = X(i,:);
H = sigmoid(transpose(theta).*Xi);
S = S + ((-Yi)*log(H)-((1-Yi)*log(1-H)));
end
J = S/m;
end
而不是对一个的引用。
答案 0 :(得分:1)
您可以为基类提供一个指示矩阵布局的状态 - 相应地具有调度矩阵操作(在基类上)。保留特殊的矩阵类用于构造,但是在应用操作后它们将忽略基础矩阵。
示例:
Matrix = IdentityMatrix operation DiagonalMatrix
这将忽略参数类型并导致具有状态'Diagonal'
的矩阵答案 1 :(得分:0)
如果您在子类中重新定义它并将它们初始化为
,则可能需要将Matrix :: operator +声明为虚拟Matrix *A = new DenseMatrix();
为什么operator +不是DenseMatrix
的成员呢?我的意思是
DenseMatrix DenseMatrix::operator+ (DenseMatrix const& right) const;
而不是
friend DenseMatrix operator+ (DenseMatrix const& left, DenseMatrix const& right);
您确定需要在派生类中重新重载operator +吗? 你不能从你的基类Matrix继承operator +吗?
修改强>
如果您的基类没有运算符+,但是您的派生类没有运算符,那么您仍然需要在基类中声明(但不是定义)一个虚拟,否则当{{{}指向它们时,派生类不能覆盖它。 1}}而不是Matrix*
。
答案 2 :(得分:0)
不确定为什么要多个+运算符。无论矩阵表示如何,矩阵加法都是相同的:
1.确保添加的基质具有相同的尺寸
2.从输入矩阵中添加相应的条目,以在输出矩阵中生成值
这些操作将在基类操作符+。
然后您需要的是在每个子类中实现getDimensions(),如果它们相等,则执行:
result.put(x,y,inputA.get(x,y)+ inputB.get(x,y));
对于矩阵中的每个条目。