Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我们可以声明一个抽象方法来返回抽象超类中的子类对象而不需要新的实例化吗?_C++_Inheritance - Fatal编程技术网

C++ 我们可以声明一个抽象方法来返回抽象超类中的子类对象而不需要新的实例化吗?

C++ 我们可以声明一个抽象方法来返回抽象超类中的子类对象而不需要新的实例化吗?,c++,inheritance,C++,Inheritance,我想构建一个类(例如VectorSpace),该类将抽象地呈现某些方法。 我最近从Java移动到C++,在java java语言中发现了一些问题。 Pc>的情况是C++不允许声明: AbstractClass methodName(…)=0 另一方面,Java允许返回类型为抽象类。 C++中不允许这样做,编译结果出错,说明抽象类不能用作方法的返回类型。br/> 我已浏览此页: 所以我用c++做了以下工作: //Fields are any classes which +,* defined on

我想构建一个类(例如VectorSpace),该类将抽象地呈现某些方法。 我最近从Java移动到C++,在java java语言中发现了一些问题。 Pc>的情况是C++不允许声明: AbstractClass methodName(…)=0
另一方面,Java允许返回类型为抽象类。 C++中不允许这样做,编译结果出错,说明抽象类不能用作方法的返回类型。br/> 我已浏览此页:
所以我用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(....);}
  }
//字段是在其上定义了+、*的任何类
模板类向量空间
{
虚拟向量空间*运算符+(常量向量空间和el)常量=0;
虚拟向量空间*运算符-()常量=0;
虚拟向量空间*运算符*(常数F&el)常数=0;
....
};
类向量:公共向量空间
{
....
向量*运算符+(常量向量空间&el)常量{返回新向量(..);}
}
然而,问题是,每当应用任何运算符(例如+,-)时,我都会使用“new”来实例化任何属于VectorSpace子类(如Vector)的类的对象,这些运算符必须手动删除。


有办法解决这个问题吗?

您可以有另一个类,比如说
VectorWrapper
,它包装指向抽象类的指针,例如通过
std::unique\u ptr
。在这个类中,您可以重载
操作符+
,将调用重定向到实现,然后返回一个新的本地构造的包装器。通过
std::unique_ptr
facility可以避免手动删除,并且您拥有按值返回的重载运算符,因此它们易于使用。请注意,操作符
new
delete
仍在引擎盖下调用,并由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;
};
类向量包装器
{
矢量包装器(std::unique_ptr ptr)
:m_impl(标准::移动(ptr))
{}
向量包装运算符+(常量向量包装和其他)
{
返回向量包装器(*m_impl+*other.m_impl);
}
私人:
std::唯一的\u ptr m\u impl;
};
<>与删除型C++成语密切相关。
编辑:您还需要实现复制构造函数和赋值来调用
std::make_unique
等。。或者如果向量是不变的——就像数学对象一样——你可以考虑使用<代码> STD::SysDypPTR ,但是它可能会更慢,这取决于代码中的代码> VCordrPraseP< <代码>的频率。

< P>你可以有另一个类,比如“代码>矢量包装器< /代码>,它将指针封装到抽象类,例如,通过
std::unique\u ptr
。在这个类中,您可以重载
操作符+
,将调用重定向到实现,然后返回一个新的本地构造的包装器。通过
std::unique_ptr
facility可以避免手动删除,并且您拥有按值返回的重载运算符,因此它们易于使用。请注意,操作符
new
delete
仍在引擎盖下调用,并由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;
};
类向量包装器
{
矢量包装器(std::unique_ptr ptr)
:m_impl(标准::移动(ptr))
{}
向量包装运算符+(常量向量包装和其他)
{
返回向量包装器(*m_impl+*other.m_impl);
}
私人:
std::唯一的\u ptr m\u impl;
};
<>与删除型C++成语密切相关。
编辑:您还需要实现复制构造函数和赋值来调用
std::make_unique
等。。或者如果向量是不变的——就像数学对象一样——你可以考虑使用<代码> STD::SysDypPTR ,但是它可能会更慢,这取决于代码中的代码> VCordRePrpuls<代码>的频率。如果您返回对临时对象的引用(并且使用
操作符+
表明您将返回一个临时对象),您将遇到其他问题。为什么称它为VectorSpace?字面意思是从向量空间派生的类对象是向量空间,而不是向量。这看起来就像是强迫C++设计java。不知道要解决的问题,总是很难确定,但是在C++中,我们可能会用向量空间来代替向量空间抽象类。操作符真的需要是虚拟的还是实际上会有相同的实现?在这些情况下,有两种不同的解决方案。您可以返回一个引用,但是
向量空间
必须位于某个地方;如果您返回对临时对象的引用(并且使用
操作符+
表明您将返回一个临时对象),您将遇到其他问题。为什么称它为VectorSpace?字面意思是从向量空间派生的类对象是向量空间,而不是向量。这看起来就像是强迫C++设计java。不知道要解决的问题,总是很难确定,但是在C++中,我们可能会用向量空间来代替向量空间抽象类。操作符真的需要是虚拟的还是实际上会有相同的实现?在这些情况下,有两种不同的解决方案。