Вызов метода объекта shared_ptr - PullRequest
1 голос
/ 16 февраля 2020

Это кажется довольно глупым вопросом, поэтому, пожалуйста, потерпите меня. Я использую умные указатели вместо необработанных указателей в моих программах. Я советую не использовать сырые указатели или смешивать их как можно больше. Я тоже это понимаю. Я также знаю, что указатели должны использоваться только в тех случаях, когда это необходимо.

class Foo{
  private: int val;
  public: 
    Foo(int v) :val(v){}
    int getvalue() const { return val; }
};

std::shared_ptr<Foo> foo = std::make_shared(Foo(10));

int v;

//Option I
v=foo->getvalue();

//Option II
v=foo.get()->getvalue();

Я чувствую, что вариант I является более правильным, поскольку вариант II использует необработанный указатель. Но использование необработанного указателя может не повредить, так как я не выделяю и не освобождаю.

Часто я путаюсь с этими двумя вариантами. Какой из них предпочтительнее? Они просто одинаковые? Спасибо.

Ответы [ 3 ]

4 голосов
/ 16 февраля 2020

Сырые указатели не враги. Мы не можем написать ни одной полезной программы на C ++ без них в одной форме или форме. Проблема в том, что владеет необработанными указателями. Они не имеют четкого владения семантией c, связанной с их типом, и поэтому программисту приходится выполнять трудную задачу по управлению временем жизни вручную. Не бойтесь передавать необработанный указатель в качестве ручки, если вам нужно.

Что приводит нас к следующему пункту. Оба метода, которые вы продемонстрировали, основаны на сырых указателях. Перегруженный operator-> должен возвращать необработанный указатель (в конце концов), чтобы мы могли применить доступ к элементу к объекту. По сути, первая версия эквивалентна

v = foo.operator->() -> getvalue();

Она работает точно так же, как и вторая форма, только с syntacti c sugar сверху.

Вы должны предпочесть первую форму потому что это короче и читабельно. Но это не избегает необработанных указателей, это невозможно избежать.

2 голосов
/ 16 февраля 2020

Существует нет функциональной разницы между

//Option I
v=foo->getvalue();

И

//Option II
v=foo.get()->getvalue();

Но вариант II более типизирован, так почему?

Обе конструкции в этой ситуации делают одно и то же.

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

1 голос
/ 16 февраля 2020

Обе опции, вероятно, получат одинаковый результат в собранном коде. Первый вариант foo->getvalue() является предпочтительным, поскольку он обеспечивает лучшую читаемость.

...