2012-05-17 3 views
1

У меня следующая ситуация:unique_ptr установки

if (condition) 
{ 
    std::unique_ptr<AClass> a(new AClass); 

    // code that breaks various laws of physics 
} 

Но мне нужно, чтобы изменить его как указатель может теперь быть один из двух типов, но если я это сделать:

if (condition) 
{ 
    if (whichOne) 
     std::unique_ptr<AClass> a(new AClass); 
    else 
     std::unique_ptr<AClass> a(new BClass); 

    // code that fixes various laws of physics 
} 

Это не в состоянии компилировать, поскольку это выходит за рамки.

Я попытался

std::unique_ptr<AClassBase>; 

if (condition) 
{ 
    if (whichOne) 
     a(new AClass); 
    else 
     a(new BClass); 

    // code that tweaks various laws of physics 
} 

Но это не удается, как а нужно использовать функцию-член не от основания, и у меня нет доступа к коду для базового класса.

Должен быть изящный способ обойти это, но я не вижу его, не так ли?

+0

Чтобы уточнить: как 'AClass', так и' BClass' наследуют от 'AClassBase', и оба содержат некоторую функцию-член, которая * не * появляется в базовом классе (который вы не можете изменить)? – BoBTFish

+0

Это правильно. – Stefan

+6

Как бы вы написали это с помощью обычных указателей? Вы не можете объявить один указатель, который охватывает оба случая, поскольку вы хотите использовать реальные классы, а не базовый класс. Таким образом, проблема заключается не в unique_ptr, а в том, что вы пытаетесь избежать использования базового класса. –

ответ

5

Вы можете просто реорганизовать в

std::unique_ptr<AClassBase> base; 
    if(condition) 
    { 
     if(whichone) 
     { 
     std::unique_ptr<AClass> a(new AClass); 
     // Break laws of physics with an AClass 

     base = std::move(a); 
     } 
     else 
     { 
     std::unique_ptr<BClass> b(new BClass); 
     // Break laws of physics with an BClass 

     base = std::move(b); 
     } 
    } 
+0

Это может быть так! – Stefan

5

Это не может скомпилировать как выходит за рамки

Используйте reset функцию чтобы исправить, что:

std::unique_ptr<AClassBase> a; 

if (condition) 
{ 
    if (whichOne) 
     a.reset(new AClass); 
    else 
     a.reset(new BClass); 
} 
+0

Спасибо, но у этой проблемы есть такая же проблема. Он не компилируется, потому что код (в примере, нарушающий закон физики) использует функции, недоступные в базовом классе. :-( – Stefan

+1

Ответы _It не удается скомпилировать, поскольку проблема выходит из области. –

+1

Извините, да, это ответ на эту часть. Я должен был правильно прочитать ваш ответ! – Stefan

0

One вариант должен использовать ?::

std::unique_ptr<AClassBase> a(whichOne ? (new AClass) : (new BClass)); 

Но я лично сделал бы это только в том случае, если вся строка может вместить до 70 символов или около того.

В противном случае я бы использовал reset, как и другие, чтобы установить цель общего указателя после его создания.

+0

Не будет ли это скомпилировать, если опция BClass, поскольку указатель настроен на использование AClass? – Stefan

+0

@SteveTaylor Исходя из того, что OP включал 'std :: unique_ptr a (новый BClass);' в своем примере кода я предположил, что 'AClass' был базовым классом для' BClass'. Более внимательно, похоже, что «AClassBase» на самом деле является базовым классом; Я изменил свой ответ на использование 'std :: uniqu_ptr ' –