如何更改返回对象基类的实现';当对象返回C++; 我在C++中有一个现有的应用程序,它有一个自定义的 ArrayBase 类,它管理存储和访问一个连续分配的内存区域。我有一个单独的ItrBase类,用于访问ArrayBase中的数据ArrayBase有一个createItr()函数,该函数当前返回一个ItrBase对象
我需要扩展如何更改返回对象基类的实现';当对象返回C++; 我在C++中有一个现有的应用程序,它有一个自定义的 ArrayBase 类,它管理存储和访问一个连续分配的内存区域。我有一个单独的ItrBase类,用于访问ArrayBase中的数据ArrayBase有一个createItr()函数,该函数当前返回一个ItrBase对象,c++,inheritance,reference,virtual,return,C++,Inheritance,Reference,Virtual,Return,我需要扩展ArrayBase以使用多个内存分配,而不是一个连续的内存分配。为此,我创建了一个增强Darray类。要使此EnhancedArray与现有应用程序兼容,它的createItr()函数必须返回与新的多内存分配一起工作的内容 因此,我创建了一个派生的EnhanceItr类来实现这一点。 我的问题是,我无法找到一种方法来处理数百个这样的代码: ItrBase anIterator = anArray.createItr(); ... double x = anIterator.getDat
ArrayBase
以使用多个内存分配,而不是一个连续的内存分配。为此,我创建了一个增强Darray
类。要使此EnhancedArray
与现有应用程序兼容,它的createItr()
函数必须返回与新的多内存分配一起工作的内容
因此,我创建了一个派生的EnhanceItr
类来实现这一点。
我的问题是,我无法找到一种方法来处理数百个这样的代码:
ItrBase anIterator = anArray.createItr();
...
double x = anIterator.getData();
EnhancedItr itr1 = ...;
BaseItr itr2 = itr1; // copy by-value
cout << itr2.vfunc(); // prints 1, not 0
当anArray
是EnhancedArray
时,使用EhancedItr
的getData()
函数
下面是一个简单的应用程序,说明了我的基本安排
#include <iostream>
using namespace std;
class ItrBase {
public:
ItrBase() { cout << "ItrBase constructor.\n"; };
~ItrBase() { cout << "ItrBase destructor.\n"; };
virtual int vfunc() {return 1;};
};
class EnhancedItr : public ItrBase {
public:
EnhancedItr() { cout << "EnhancedItr constructor.\n"; };
~EnhancedItr() { cout << "EnhancedItr destructor.\n"; };
int vfunc() {return 0;};
};
class ArrayBase {
public:
ArrayBase() { cout << "ArrayBase constructor.\n"; };
~ArrayBase() { cout << "ArrayBase destructor.\n"; };
virtual ItrBase & createItr() {cout << "in AB's createItr()\n"; return *new ItrBase(); };
};
class EnhancedArray : public ArrayBase {
public:
EnhancedArray() { cout << "EnhancedArray constructor.\n"; };
~EnhancedArray() { cout << "EnhancedArray destructor.\n"; };
EnhancedItr & createItr() {cout << "in EA's createItr()\n"; return *new EnhancedItr(); };
};
int main()
{
ArrayBase ab;
EnhancedArray ea;
ItrBase itr = ab.createItr();
ItrBase eitr = ea.createItr(); //EnhancedItr assigned to ItrBase
cout << "ArrayBase's Itr .vfunc(): " << itr.vfunc() <<std::endl;
cout << "EnhancedArray's Itr .vfunc(): " << eitr.vfunc() <<std::endl;
return 0;
}
#包括
使用名称空间std;
类库{
公众:
ItrBase(){cout当然,如果允许您重写ItrBase
,那么您可以使用委托将所有函数调用传递给一个实现类,该类由指针或引用持有,这样多态性就生效了。这看起来很像pimpl。调用方根本不必编写,只需重新编译即可
编辑:不熟悉pimpl的人的代码
struct ItrBase
{
struct ItrImpl
{
virtual ~ItrImpl(){}
virtual int vfunc() = 0;
};
ItrBase(ItrImpl peer) : m_peer(peer) { cout << "ItrBase constructor.\n"; }
~ItrBase() { cout << "ItrBase destructor.\n"; }
int vfunc() { return m_peer->vfunc(); }
private:
const unique_ptr<ItrImpl> m_peer;
};
class ArrayBase
{
struct ItrImpl : public ItrBase::ItrImpl
{
virtual int vfunc() { return 0; }
};
public:
ArrayBase() { cout << "ArrayBase constructor.\n"; };
~ArrayBase() { cout << "ArrayBase destructor.\n"; };
virtual ItrBase createItr() { cout << "in AB's createItr()\n"; return ItrBase(new ItrImpl); };
};
class EnhancedArray : public ArrayBase
{
struct ItrImpl : public ItrBase::ItrImpl
{
virtual int vfunc() { return 1; }
};
public:
EnhancedArray() { cout << "EnhancedArray constructor.\n"; };
~EnhancedArray() { cout << "EnhancedArray destructor.\n"; };
virtual ItrBase createItr() { cout << "in EA's createItr()\n"; return ItrBase(new ItrImpl); };
};
struct-ItrBase
{
结构ItrImpl
{
虚拟~ItrImpl(){}
虚拟int vfunc()=0;
};
ItrBase(ItrImpl peer):m_peer(peer){cout您遇到了一个名为:createItr
返回一个引用的问题,然后您通过值将其复制到一个ItrBase
中。就好像您做了这样的事情:
ItrBase anIterator = anArray.createItr();
...
double x = anIterator.getData();
EnhancedItr itr1 = ...;
BaseItr itr2 = itr1; // copy by-value
cout << itr2.vfunc(); // prints 1, not 0
EnhancedItr itr1=。。。;
BaseItr itr2=itr1;//按值复制
完全不同的是你可以使用
BOOST_AUTO(iterator, array);
让编译器计算出返回类型
由于标准库不是最新的,我无法使用Ben Voigt建议的独特的\u ptr
实现。(版本>=4.3)我相信我接受了他的概念,并用基本指针实现了它。但是,请注意,这个实现不是异常安全的。ItrImpl
对象可以不删除
这是我的代码。太糟糕了,createItr()
必须返回ItrBase
对象而不是指针,否则我想我可以让auto_ptr
工作。程序执行期间的输出显示~ItrBase()每个实例只调用一次
,但我很惊讶,在从createItr()返回对象的过程中,它没有被调用。
。返回值优化
#include <iostream>
using namespace std;
struct ItrBase
{
struct ItrImpl
{
virtual ~ItrImpl(){};
virtual int vfunc() const = 0;
};
ItrBase(ItrImpl* peer) : m_peer(peer) { cout << "ItrBase constructor.\n"; };
~ItrBase() { cout << "ItrBase destructor. \n"; delete m_peer; };
int getData() const { return m_peer->vfunc(); };
private:
ItrImpl* const m_peer;
};
class ArrayBase
{
struct ItrImpl : public ItrBase::ItrImpl
{
virtual int vfunc() const { return 0; };
};
public:
ArrayBase() { cout << "ArrayBase constructor.\n"; };
~ArrayBase() { cout << "ArrayBase destructor.\n"; };
virtual ItrBase createItr() { cout << "in AB's createItr()\n"; return ItrBase(new ItrImpl); };
};
class EnhancedArray : public ArrayBase
{
struct ItrImpl : public ItrBase::ItrImpl
{
virtual int vfunc() const { return 1; };
};
public:
EnhancedArray() { cout << "EnhancedArray constructor.\n"; };
~EnhancedArray() { cout << "EnhancedArray destructor.\n"; };
virtual ItrBase createItr() { cout << "in EA's createItr()\n"; return ItrBase(new ItrImpl); };
};
int main()
{
ArrayBase ab;
EnhancedArray ea;
ItrBase itr = ab.createItr();
ItrBase eitr = ea.createItr(); //EnhancedItr assigned to ItrBase
cout << "ArrayBase's Itr .vfunc(): " << itr.getData() <<std::endl;
cout << "EnhancedArray's Itr .vfunc(): " << eitr.getData() <<std::endl;
return 0;
}
#包括
使用名称空间std;
结构ItrBase
{
结构ItrImpl
{
虚拟~ItrImpl(){};
虚拟int vfunc()常量=0;
};
ItrBase(ItrImpl*peer):m_peer(peer){我可以重写ItrBase吗。因此,如果我理解正确,我不会从ItrBase派生一个类,只是一个不同的ItrBase,它根据调用方的数据类型表现不同?我不熟悉pimpl,所以我会仔细阅读。非常感谢。你的意思不是ItrImpl()构造函数被声明为虚拟的,是吗?不,我没有(显然这个例子没有经过编译测试)。构造函数不能是虚拟的。是否使用此解决方案的唯一\u ptr集成?我以前没有使用过它,g++现在没有将其作为类型进行解析。您有什么版本的g++?最新版本应该包括std::unique\u ptr
,旧版本可以使用boost::unique\u ptr
或std::auto\u ptr
并提供拷贝构造函数和赋值操作符,窃取m_对等方的所有权。