首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >运行时多态性c++11和运算符重载

运行时多态性c++11和运算符重载
EN

Stack Overflow用户
提问于 2019-02-12 00:34:05
回答 2查看 97关注 0票数 0

假设我正在尝试实现一些数学向量类。

作为向量接口将在多个地方使用:基于数组的向量,矩阵作为向量接口对象返回列和行等。

我想为我的向量重载+,-运算符。每个运算符都应该返回某个向量实现类的新构造对象。

但正如你所知道的,操作符重载应该返回值或引用。我不能返回值,因为我需要运行时多态性,所以我只能使用引用。但是为了有一个在函数调用后不会死的引用,应该在堆中创建对象。

那么,我应该如何管理这种情况呢?

附注:我可以创建一个shared_ptr并返回一个包含值的引用,但这看起来不是一个好的做法。

代码语言:javascript
复制
typedef unsigned int vector_idx_t;

template <class T, vector_idx_t size>
class vector {
public:
    virtual ~vector();

    virtual T& operator[](const vector_idx_t idx) = 0;
    virtual vector<T, size>& operator+ (const T& a) const = 0;
    virtual vector<T, size>& operator- (const T& a) const = 0;
    virtual vector<T, size>& operator* (const T& a) const = 0;
    virtual vector<T, size>& operator/ (const T& a) const = 0;

    virtual vector<T, size>& operator+ (const vector<T, size>& vec2) const = 0;
    virtual vector<T, size>& operator- (const vector<T, size>& vec2) const = 0;
};

template <class T, vector_idx_t size>
class array_vector: public vector<T, size> {
private:
    std::array<T, size> m_elements;
public:
    array_vector();
    array_vector(std::array<T, size> elements);
    array_vector(const vector<T, size>& vec2);
    array_vector(std::initializer_list<T> elems);

    virtual ~array_vector();

    virtual T& operator[](const vector_idx_t idx) {
           return m_elements[idx];
        }

    virtual vector<T, size>& operator+ (const T& a) const {
        std::array<T, size> e;
        for (vector_idx_t i = 0; i < size; ++i) {
            e[i] = m_elements[i] + a;
        }
        auto v = std::make_shared<array_vector<T, size>>(elems);
        return *v;
    }
};
EN

回答 2

Stack Overflow用户

发布于 2019-02-12 01:03:48

我建议对您的设计稍作修改,以适应实现的多态特性。

在包含vector.

  • Make polymorphic.

  • Use polymorphic.

实现特定详细信息的情况下,不要使

  1. 成为vector Data

这将允许您按值或按引用将vector返回给接口。

票数 1
EN

Stack Overflow用户

发布于 2019-02-12 01:41:52

子类型的多态性并不是解决所有问题的答案。我知道你想做什么,但我不太明白为什么按模板多态解决方案是不够的,你需要有虚拟运算符(它根本不能很好地与按子类型的多态混合)。

您希望能够在混合类型的向量上定义操作,以便可以计算真实容器和容器代理之间的结果。

这首先应该要求你有一个你需要的基本的最终类型,一个矩阵列的代理不是一个真正的容器,而是一个容器的视图,所以添加其中的两个应该返回一个真正的容器(例如。由实际的std::array支持的容器?)。

类似的设计可以通过如下方式进行管理

代码语言:javascript
复制
template<typename ContainerType, typename ElementType>
class vector_of : public ContainerType
{
public:
  vector_of(const ContainerType& container) : ContainerType(container) { }

  vector_of<ContainerType, ElementType> operator+(const ElementType& a) const
  {
    vector_of<ContainerType, ElementType> copy = vector_of<ContainerType,ElementType>(*this);
    std::for_each(copy.begin(), copy.end(), [&a](ElementType& element) { element += a; });
  }

  template<typename T>
  vector_of<ContainerType, ElementType> operator+(const vector_of<T, ElementType>& a) const
  {
    vector_of<ContainerType, ElementType> copy(*this);
    auto it = copy.begin();
    auto it2 = a.begin();

    while (it != copy.end() && it2 != a.end())
    {
      *it += *it2;

      ++it;
      ++it2;
    }

    return copy;
  }
};

这里的诀窍是operator+是一个接受ElementType元素的泛型容器的模板方法。代码假设这些类型的容器提供了返回迭代器的beginend方法(这在任何情况下都是一个明智的选择,因为它可以很好地与STL一起工作)。

使用您可以执行以下操作:

代码语言:javascript
复制
class MatrixRowProxy
{
private:
  int* data;
  size_t length;

public:
  MatrixRowProxy(int* data, size_t length) : data(data), length(length) { }

  int* begin() const { return data; }
  int* end() const { return data + length; }
};

vector_of<std::array<int, 5>, int> base = vector_of<std::array<int, 5>, int>({ 1, 2, 3, 4, 5 });
vector_of<std::vector<int>, int> element = vector_of<std::vector<int>, int>({ 2, 3, 4, 5, 6 });

int* data = new int[5] { 10, 20, 30, 40, 50};
vector_of<MatrixRowProxy, int> proxy = vector_of<MatrixRowProxy, int>(MatrixRowProxy(data, 5));

auto result = base + element + proxy;
for (const auto& t : result)
  std::cout << t << std::endl;

所以你可以添加不同种类的向量,而不需要任何virtual方法。

当然,这些方法需要在方法中创建一个新的结果对象。这是通过将其复制到新的vector_of<ContainerType, ElementType>中来完成的。没有什么可以阻止你添加第三个模板参数,比如VectorFactory,它负责这一点,这样你就可以使用矢量,它也是这些运算符的LHS上的包装器。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54635065

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档