【问题标题】:performing function with classes of similar type C++使用类似类型 C++ 的类执行功能
【发布时间】:2014-10-24 12:55:03
【问题描述】:

我想实现矩阵的表示。 为此,我有两种类型的矩阵 - 常规矩阵和稀疏矩阵,它们的不同之处在于 实现 - 一个持有一个向量,第二个持有一个索引和值的映射, 都继承自 Matrix 类。

我想实现 + 运算符,它在 Matrix 上运行并接收另一个 Matrix。 但是当我实现 + 运算符时,我可能会收到参数稀疏/正则矩阵。

有什么方法可以接收一个矩阵,我不知道它是什么类型的2, 并执行 + 运算符? 意思是,如果在 SparseMatrix 类中我收到稀疏/正则矩阵,我该如何实现运算符,以便无论我得到两种类型中的哪一种,它都会起作用?

Matrix & operator+ (Matrix other)
{
    ...
}

【问题讨论】:

  • 通过引用传递矩阵并使用多态(一个常见的矩阵基类)。

标签: c++ inheritance interface iterator polymorphism


【解决方案1】:

我可能会实现operator+ 的两个版本,并让它们调用辅助模板方法:

template <typename ITER>
Matrix add (ITER other_it) {
    //...
}

Matrix operator+ (RegularMatrix other)
{
    return add(other.begin());
}

Matrix operator+ (SparseMatrix other)
{
    return add(other.begin());
}

您可以将operator+ 设为模板,但这样可以确保您只允许那些Matrix 类型。

正如我所指出的,您不应返回来自+ 的引用,因为结果需要指向操作返回后存在的实例。

【讨论】:

  • 我认为应该注意的是,从二元运算符返回引用不是一个好主意。事实上,在这种情况下有 UB,因为您要返回对局部变量的引用(注意您按值传递矩阵)
  • 关于价值传递,我喜欢好老的const&amp;,但我不想重新开始“想要速度?传递价值!”在这里再次辩论.
  • @Manu343726:关于返回参考的好点。谢谢。至于传入引用与复制,性能取决于编译器实现复制省略的程度。
【解决方案2】:

我们可以使用多态性来创建矩阵的不同实现。通过Matrix的公共接口,各个实现可以交互。

   class Matrix
   {
      class iterator { ... }

      friend Matrix operator+(const Matrix &lhs, const Matrix &rhs)
      {
         // iterate, add, and return new matrix
      }
   };

   class SpareMatrix : public Matrix
   {
      iterator begin() { ... }
   };

【讨论】:

  • 谢谢,但是我怎样才能用两种不同的矩阵类型进行加法呢?如果一个包含地图,第二个包含矢量,我无法概括它们两者之间的加法
  • 我改变了主意。 Matrix 基类将具有重载的加法运算符,并且每个子类必须唯一地实现迭代器以使用矩阵的不同实现。
【解决方案3】:
class Matrix
{
public:
    virtual ~Matrix() {}

    virtual Matrix& operator+(Matrix& other) = 0;
};

class MatrixSparse : public Matrix
{
public:
    virtual ~MatrixSparse() {}
    virtual Matrix& operator+(Matrix& other)
    {
        MatrixSparse* sparse = dynamic_cast<MatrixSparse*>(&other);
        // TODO
    }
};

class MatrixRegular : public Matrix
{
public:
    virtual ~MatrixRegular() {}
    virtual Matrix& operator+(Matrix& other)
    {
        MatrixRegular* regular = dynamic_cast<MatrixRegular*>(&other);
        // TODO
    }
};

另外,another SO thread 处理抽象类中的运算符重载问题。

【讨论】:

    猜你喜欢
    • 2011-01-25
    • 2012-10-04
    • 2011-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-21
    相关资源
    最近更新 更多