制作一个未知的类实例

时间:2018-10-30 10:08:33

标签: c++ class reference

这听起来很简单,但现在我完全感到困惑。如何在不将类定义包含在头文件中的情况下防止类的实例超出范围?我可以使用某种前向参考。我使用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维护引用计数,但不能对其进行显式操纵。 任何见识将不胜感激。 HJB

1 个答案:

答案 0 :(得分:0)

这里要注意的第一件事是,由于您已经将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的唯一实例,那么您几乎可以肯定希望更像后者。