【问题标题】:Use existing base class object when allocating a derived class分配派生类时使用现有的基类对象
【发布时间】:2013-11-29 13:34:45
【问题描述】:

我需要 C++ 中特定编程问题的帮助(不确定这在 C++ 中是否可行)。我需要能够访问 Base 类中的所有公共成员函数,但不想在分配 Derived 类对象时为 Base 类数据分配内存。

可以说,我有:

class Base
{
  public:
    Base();
    ~Base();
    int GetFoo() { return foo; }
    // other public member functions of Base class

  private:
    int foo;
    // other data
};

class Derived : public Base
{
  public:
    Derived(Base *BasePtr);
    Derived(Base &BaseRef);
    ~Derived();
    double GetXyz() { return xyz; }
    // other public member functions of Derived class

  private:
    double xyz;
    // other data
};

现在,假设我已经分配并初始化了一个基类。我想通过引用现有的 Base 对象来创建一个新的 Derived 类对象,并仅为 Derived 类特定的数据分配内存。按照上面的例子,我已经为基类对象中的“int foo”分配了内存,只想为派生类对象中的“double xyz”分配内存。

Base *basePtr = new Base();
Derived *derivedPtr = new Derived(basePtr); // what is the content of this function?

Derived 类的内存分配或构造函数应该是什么样的?我想继承 Base 类的所有数据和成员函数,但不做 Base 和 Derived 的“组合”数据分配。我试过重载 operator new 但没有运气。任何帮助表示赞赏。

【问题讨论】:

  • 您可能需要一个复制构造函数,或者不创建基类对象,而是在派生类中调用基类的构造函数
  • 请参阅下面我对答案 1 的评论,我无法选择不预先创建 Base 对象。

标签: c++ inheritance memory allocation


【解决方案1】:

我不确定它是否符合您的要求,但您可以简单地将存储在basePtr 中的Base 的内容复制到一个新的Derived 对象中,然后删除Base 对象并指向新的 Derived 对象和旧的 Base 指针。像这样:

Base *basePtr = new Base();
/* Do something with base here */
Derived *derivedPtr = new Derived(basePtr);
delete basePtr;
basePtr = derivedPtr;
derivedPtr = 0;

这样您最终将只得到一个对象(Derived 类型),并且不必存储指向它的单独指针,也不必存储 Base 对象,这似乎正是您所需要的。

更新:

在我的情况下,我无法删除 Base 对象,因为我会创建数百万个(使用千兆字节的 RAM 空间)并且人们可能正在使用指向这些对象的指针/引用,因此将它们复制到派生对象并删除旧的基础对象对我不起作用。

在这种情况下,也许你应该尝试做一个“可扩展*结构的包装器。首先创建一个没有任何方法或成员的简单类:

class Additional{};

然后创建一个包装器结构:

struct wrapper{
    Base *basePtr;
    Additional *moreInfo;
}

然后,不要从Base 派生Derived 类,而是从Additional 派生它。而不是存储数百万个Base 指针,而是存储数百万个wrapper 指针。它会让你的代码更长更难理解,但它会做你需要的。好吧 - 除非您的 Derived 类添加的唯一内容是指针或任何占用较少大小的数据。

如果你在Base 中有virtual 函数,为了在新的层次结构中使用它们,oyu 每次都需要检查:

wrapper *wrapperPtr = &alreadyCreatedSomewhereWrapper;
if(wrapperPtr->moreInfo)
    wrapperPtr->moreInfo->function();
else
    wrapperPtr->basePtr->function();

【讨论】:

  • 感谢您的回答,帕维尔。不幸的是,就我而言,我无法删除 Base 对象,因为我会创建数百万个(使用千兆字节的 RAM 空间)并且人们可能正在使用对这些对象的指针/引用,因此将它们复制到 Derived 对象并删除旧的 Base对象对我不起作用。如果在 C++ 中没有技巧,我所能想到的就是从头开始创建派生对象(这将浪费空间,直到派生数据在以后的计算阶段实际使用)。
【解决方案2】:

使用多重继承。

class Base()
class Derive1() : Base 
class Derive2() : Base
class MostDerive() : Derive1 , Derive2

MostDerived() 会很薄。 Derive1 和 Derive2 需要确定性地构造,但这可以强制执行,或者可以使用一些 Init() 函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-20
    • 1970-01-01
    • 2023-03-14
    • 2020-08-06
    • 1970-01-01
    • 2020-03-24
    • 2018-02-02
    • 1970-01-01
    相关资源
    最近更新 更多