Возврат ссылки на неопределенный указатель - PullRequest
0 голосов
/ 05 июня 2018

Если класс имеет неопределенный указатель в качестве частной переменной, как проверить, является ли указатель действительным, если функция наблюдателя выглядит следующим образом:

Class Foo
{
  private:
    Object * object;
  public:
    Foo();
    virtual const Object & get_object() const { return * object; }
}

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

Я думаю, что мы все неправильно поняли проблему ОП, и это касается меня.ОК, он не смог инициализировать object, но, если я правильно понял, он не об этом.Мне кажется, он хочет знать, как ссылка может «указывать» на недопустимый объект.

Ну, обычно это невозможно.Контракт, когда возвращается ссылка, заключается в том, что он всегда будет указывать на что-то действительное, и , в частности, не будет, под прикрытием, содержать nullptr.Это , почему вы возвращаете ссылку, а не указатель.Потому что она несет эту гарантию.

Итак, @Ralff загнал себя в угол?Ну, не совсем.Конечно, обычным решением будет просто get_object() вернуть указатель в первую очередь, но он, очевидно, не хочет этого делать.

Хорошим решением здесь является сохранение объекта типа Object вокруг этого служит заполнителем для недопустимого объекта.Тогда это легко.Я перестану вафляться и выложу код:

#include <iostream>

class Object
{
    // ...

public:
    static Object invalid_object;
    bool is_valid () const { return this != &invalid_object; };
};

Object Object::invalid_object;

class Foo
{
private:
    Object * object = nullptr;
public:
    Foo() { }
    virtual const Object & get_object() const { return (object) ? *object : Object::invalid_object; }
};

А теперь вы можете сделать:

int main ()
{
    Foo foo_obj;
    const Object& obj = foo_obj.get_object ();
    if (obj.is_valid ())
        std::cout << "object is valid" << std::endl;
    else
        std::cout << "object is invalid" << std::endl;
    return 0;
}

Live демо .

OPдля других подходов проверьте также std :: необязательный или рассмотрите , генерирующее исключение из get_object() (хотя это не мой выбор).

0 голосов
/ 05 июня 2018

В конструкторе (в списке инициализатора) вы можете установить Object *object как nullptr

Foo::Foo()
:
object(nullptr)
{}

, а в методе get_object() выполнить проверку if, чтобы убедиться, чтоobject не равен нулю перед разыменованием:

if(object)
  return *object;
else
  // create and return a new Object depending on your use-case.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...