C ++: Ссылки как аргументы конструктора, помощь - PullRequest
0 голосов
/ 07 июля 2010

У меня есть базовый класс (Base), конструктор которого принимает ссылку в качестве аргумента.В моем производном классе это конструктор, я вызываю конструктор суперкласса и, конечно, мне нужно передать ссылку в качестве аргумента.Но я должен получить этот аргумент из метода, тип возвращаемого значения по значению ...

Я приведу короткий пример:

class Base
{
public:
    Base(MyType &obj) { /* do something with the obj */}
};

class Derived : public Base
{
public:
    Derived(MyOtherType *otherType) :
         Base(otherType->getMyTypeObj()) // <--- Here is the error because (see *)
    {
         // * 
         // getMyTypeObj() returns a value and
         // the Base constructor wants a reference...
    }
};

class MyOtherType
{
public:
    MyType getMyTypeObj()
    {
         MyType obj;
         obj.setData( /* blah, blah, blah... Some data */);
         return obj; // Return by value to avoid the returned reference goes out of scope.
    }
};

Как мне решить эту проблему?

Ответы [ 4 ]

3 голосов
/ 07 июля 2010

Измените Базовый класс на: class Base { public: Base(const MyType &obj) { /* do something with the obj */} };

Обновление: если вы хотите изменить obj, у вас явно не может быть ссылки const.В этом случае вы можете либо:

1) передать параметр по значению.Это приведет к дополнительным издержкам для копии, но избегайте ее явного освобождения позже.

2) Измените MyOtherType::getMyTypeObj() на

MyType& MyOtherType::getMyTypeObj()
{
    MyType* obj = new MyType();
    obj->setData( /* blah, blah, blah... Some data */);
    return *obj;

}

В этом случаене забудьте удалить объект после того, как с ним покончено.

1 голос
/ 07 июля 2010

Серьезно?На ваш вопрос есть ответ.Измените либо тип параметра на конструктор Base, либо тип возвращаемого значения getMyTypeObj (), чтобы типы были совместимы.

0 голосов
/ 07 июля 2010

Мне кажется, что это можно решить двумя способами.

  1. Измените конструктор Base, чтобы он принимал объект MyType по значению, а не по ссылке.Это скопирует временный объект и решит проблемы с областью действия.

  2. В качестве альтернативы, вы можете сделать копию объекта MyType в Derived и передать ссылку на него.

class Derived : public Base
{
public:
    Derived(MyOtherType *otherType) :
        Base(m_myType) ,
        m_myType(otherType->getMyTypeObj())
    {
        // ...
    }
private:
    MyType m_myType;
};

Вариант 1 проще, и я, как правило, рекомендую его.
Вариант 2 на случай, если какое-то другое ограничение не позволяет изменить конструктор Base,

0 голосов
/ 07 июля 2010

Проблема вызвана тем, что GetMyTypeObj () возвращает копию obj, которая основана на стеке, поэтому компилятор создает временную переменную внутри вашего конструктора, область действия которой - это просто вызов конструкции Base ().

...