Как мне создать базовый класс, который получает ссылочный аргумент? - PullRequest
3 голосов
/ 07 февраля 2012

Я не могу скомпилировать следующий код, используя g ++ 4.1.2:

#include <memory>

class A
{
    public:
};

std::auto_ptr<A> GetA()
{
    return std::auto_ptr<A>(new A);
}

class B
{
    B(std::auto_ptr<A>& pA)
    {
    }
};

class C : public B
{
    C() : B(GetA())
    {
    }
};

Я получаю:

неверное приведение выражения rvalue типа std::auto_ptr<A> к типу std::auto_ptr<A>&

Проблема в том, что я не могу определить переменную и передать ее ссылку, потому что я нахожусь в списке инициализации.

Как я могу это сделать, когда мне разрешено менять только класс C?

Ответы [ 2 ]

3 голосов
/ 07 февраля 2012

Если вы можете только изменить C, вы можете сделать что-то вроде:

class C: public B
{
    explicit C(std::auto_ptr<A>& pA) : B(pA) {}

public:
    static C *GetC()
    {
        std::auto_ptr<A> pA = GetA();
        return new C(pA);
    }
};

Проблема заключается в попытке привязать неконстантную ссылку к временному значению, возвращенному GetA,Если вы можете сначала присвоить это переменной, у вас есть lvalue, и она работает нормально.

Как сказал Алекс B , сказал (удаленный ответ), если вы можете изменить B, это будетлучше взять этот auto_ptr аргумент по значению;и если вы можете изменить компилятор, было бы лучше использовать unique_ptr и вместо этого переместить семантику.

0 голосов
/ 07 февраля 2012

Зависит от того, что B делает с переданной ссылкой.

  • Если B собирается взять копию аргумента, то сделать аргумент const &
  • Если Bбудет содержать ссылку на аргумент, тогда вам нужно, чтобы все, что передано, имело более длительный срок службы, чем экземпляр B. (Как уже упоминалось, временный объект, созданный при вызове GetA (), этого не делает).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...