【问题标题】:Making an unknown class instance制作一个未知的类实例
【发布时间】:2018-10-30 10:08:33
【问题描述】:

这听起来很简单,但现在我完全糊涂了。在我的头文件中不包含类定义的情况下,如何防止类的实例超出范围?我可以使用某种前向参考吗?我使用 C++ VS2017。我希望下面的伪代码能说明我的意图。

// MyHeader.h
class X
{
    class ThirdPartyClass &tpc;  // This must require a forward definition
    // and many other things
}

// My program
#include "MyHeader.h"
int main ()
{
    X x;
    foo(x);
}

// A separately compiled module
#include "MyHeader.h"
#include "ThirdPartyClass.hpp" // (Very large)
void foo (class X &x)
{
    ThirdPartyClass localtpc;
    x.tpc = &localtpc;
}

我知道它不会赢得最佳代码奖。我想要做的是在 foo() 退出后将 localtpc 的实例保留在内存中。 ThirdPartyClass.hpp 很大,我不想在 MyHeader.h 中包含 ThirdPartyClass.hpp。使用 void * 来保存引用不起作用,localtpc 的实例被破坏。 ThirdPartyClass 维护一个引用计数,但它不能被显式操作。 任何见解将不胜感激。 哈士奇

【问题讨论】:

  • 然后分配具有动态存储持续时间的ThirdPartyClass 对象。那是auto p_obj{::std::make_unique<ThirdPartyClass>()}; 并将其移动到tpc(这也应该是一个智能指针)
  • 您的 X 类有 .cpp 文件吗?如果是这样,您打算如何在不包含类定义的情况下使用tpc 成员,如果您不在 X 类中使用 tpc,为什么它根本是该类的成员?
  • @VTT 答案进入答案部分好友
  • @r3mus。 X 类必须持有对 TPC 实例的引用。

标签: c++ class reference


【解决方案1】:

这里首先要注意的是,由于您已将 tpc 定义为引用,因此必须对其进行初始化(而不仅仅是分配给),因此即使在 x.tpc = &localtpc; 的一般顺序上也行不通.

至于什么会起作用,我可以看到(至少)两种明显的可能性。创建一个 ThirdPartyClass 的单个实例,然后初始化所有 X 对象以包含指向该单个实例的指针:

// X.h
class X { 
    ThirdPartyClass &x;
public:
    X();
};

// X.cpp
#include "ThirdPartyClass.hpp"

X::X()
    : x(holder())
{}

ThirdPartyClass &holder() { 
    static ThirdPartyClass foo;
    return foo;
}

另一个明显的可能性是使用new 创建一个实例,并从那里初始化您的引用:

// X.h
class X { 
    ThirdPartyClass &x;
public:
    X();
};

// X.cpp
#include "ThirdPartyClass.hpp"

X::X()
    : x(* new ThirdPartyClass)
{}

至于哪个是首选:这实际上取决于您如何使用事物。如果您希望x 的所有实例共享ThirdPartyClass 的单个实例,因此(例如)通过一个修改应该反映在所有其他实例中,那么您几乎肯定想要至少与前者大致相似的东西。

另一方面,如果x 的每个实例都应该有一个唯一的ThirdPartyClass 实例,那么您几乎肯定想要更像后者。

【讨论】:

  • 谢谢 Jerry,我发现您的解决方案是最容易实施的。 ThirdPartyClass 有几个实例,所以我使用简单的 new() 并避免使用本地实例。在 X 类中,我使用 void* 来预定义指针。
  • @DuxburyDutch:还有一点:作为一般规则,如果您要使用new,您最好使用某种智能指针类来自动释放指针当拥有的对象被销毁时。
猜你喜欢
  • 2016-08-17
  • 1970-01-01
  • 2017-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多