c++ - 我们可以声明一个抽象方法来返回抽象父类(super class)中的子类对象而无需新的实例化吗?

标签 c++ inheritance

我想构建一个类(例如 VectorSpace),该类将具有抽象地存在于类中的某些方法。 我最近从 Java 转向了 C++,我发现在尝试重新表述 Java 中的通用抽象方法声明时遇到了问题

情况是c++不允许这样的声明:
抽象类方法名(...) = 0;
另一方面,Java 允许返回类型是抽象类。 这在 C++ 中是不允许的,并且编译会导致错误,指出抽象类不能作为方法的返回类型。
我浏览了这个页面:returning an abstract class from a function .
所以我在 C++ 中做了以下操作:

//Fields are any classes which +,* defined on them
  template<class F> class VectorSpace
  {
    virtual VectorSpace<F>* operator+(const VectorSpace<F>& el) const =0;
    virtual VectorSpace<F>* operator-() const =0;
    virtual VectorSpace<F>* operator*(const F& el) const =0;
    ....
  };
  class Vector : public VectorSpace<double>
  {
      ....
      Vector* operator+(const VectorSpace<double>& el) const {return new Vector(....);}
  }

但是,这样做的问题是,每当应用任何运算符(例如 +、-)时,我将使用“new”为作为 VectorSpace 的子类(如 Vector)的任何类实例化一个对象,这必须手动删除。

有没有办法解决这个问题?

最佳答案

你可以有另一个类,比如 VectorWrapper ,它包装了一个指向抽象类的指针,例如通过 std::unique_ptr<VectorSpace<double> > .在这个类中你可以重载 operator+将调用重定向到实现,然后返回一个新的本地构造的包装器。 std::unique_ptr 避免了手动删除设施,并且您有按值返回的重载运算符 - 因此它们易于使用。请注意运算符 newdelete仍然在引擎盖下调用并由 VectorWrapper 封装。

class VectorWrapper 
{
    VectorWrapper(std::unique_ptr<VectorSpace<double> > ptr)
        : m_impl(std::move(ptr))
    {}
    VectorWrapper operator+(const VectorWrapper& other)
    {
         return VectorWrapper(*m_impl + *other.m_impl);
    }
private:
    std::unique_ptr<VectorSpace<double> > m_impl;
};

它与类型删除 C++ 习语密切相关。

编辑:您还需要实现复制构造函数和赋值来调用 std::make_unique等等。或者如果 vector 是不可变的——就像数学对象一样——你可以考虑使用 std::shared_ptr , 但它可能会更慢,具体取决于VectorWrapper 的频率。已复制到您的代码中。

关于c++ - 我们可以声明一个抽象方法来返回抽象父类(super class)中的子类对象而无需新的实例化吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58680916/

相关文章:

c++ - 在 Yosemite 上安装 wx-widgets 让我发疯

c++ - 获取大小由变量定义的数组变量以进行赋值?

java - 不改变代码调用父类方法

c++ - 垃圾值 - C++ 中的继承

c# - 使用 partial 从自动生成的 linq-sql 对象中抽象方法

C++ 如何从字符数组(或 std::string)解析整数(可能还有 double )?

c++ - SFML 中的 Visual Studio 错误 : <Information not available, 没有为 sfml-audio-d-2.dll 加载符号 >

c++ - 为库输入参数的正确方法

c++ - 将具有特殊结构的子类映射到同一基类的另一个子类

ruby - Ruby 中的“super”和继承