Создание неизвестного экземпляра класса - PullRequest
0 голосов
/ 30 октября 2018

Звучит просто, но сейчас я совершенно сбит с толку. Как я могу предотвратить выход экземпляра класса из области видимости, не включая определение класса в мой заголовочный файл? Могу ли я использовать какую-то прямую ссылку. Я использую 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;
}

Я знаю, что это не выиграет трофей за лучший код. Я хочу сохранить экземпляр localtpc в памяти после выхода из foo (). ThirdPartyClass.hpp огромен, и я не хочу включать ThirdPartyClass.hpp в мой MyHeader.h. Использование void * для хранения ссылки не работает, экземпляр localtpc разрушается. ThirdPartyClass поддерживает счетчик ссылок, но им нельзя манипулировать явно. Любое понимание будет с благодарностью. HJB

1 Ответ

0 голосов
/ 30 октября 2018

Первое, что следует отметить, это то, что, поскольку вы определили 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, то вы почти наверняка захотите что-то более похожее на последнее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...