Если мой класс правильно управляет ресурсом, то какой смысл в умных пуантах? - PullRequest
3 голосов
/ 31 октября 2019

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

У меня один вопрос: если мой класс управляет ресурсом в своих конструкторах и деструкторах, применяя некоторые правилабольшой палец, как Большой 5 и Большой 3 ... Должен ли я по-прежнему использовать умные указатели? или мой класс является альтернативой им. Потому что, как я читал в выпуске C ++ primer 5, умные указатели решали проблемы, с которыми сталкивались необработанные указатели, такие как утечки памяти, двойное удаление указателей и доступ к висящему указателю ... Мой класс может избежать этих проблем:

class BallGame {
    public:
        using Resource = int;

        BallGame(int);
        BallGame(const BallGame&);
        BallGame(BallGame&&);
        BallGame& operator=(const BallGame&);
        BallGame& operator=(BallGame&&);
        ~BallGame();
    private:
        Resource m_res;
};
  • Считаете, что ученик моего класса делает правильную работу, поэтому я могу избежать умного указателя?

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

  • Они действительно для "тупых классов" (классов, которые определяют конструкторы, но не деструкторы с хорошим поведением), как в учебнике по С ++.

Ответы [ 3 ]

5 голосов
/ 31 октября 2019

Ваш вопрос может быть прочитан как

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

Да , но почему? Когда вам нужен динамический массив, вы переопределяете базовую семантику std::vector вручную каждый раз, когда вам это нужно? Я так не думаю.

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

1 голос
/ 31 октября 2019

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

1 голос
/ 31 октября 2019

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

int* ptr = new int[1024];
// oh my God! forgot to free it then welcome to memory leak

std::string* pStr = new std::string("Hello");
delete pStr;

//...
// and at some point in the program you think it is time to free pStr which has been already freed (among hundreds of code lines) then welcome to U.B.
 std::cout << *pStr << std::endl; // pStr is a dangling pointer. U.B

Чтобы решить эту проблему с помощью интеллектуальных указателей:

std::unique_ptr<int> upi = std::make_unique(7);
// use upi effectively and don't care about freeing it because it automatically will be freed for you.
  • Еще одна причина, по которой ваш класс не может поддерживать, - это совместное использование одного и того же объекта среди множества объектов. Фактически, вы можете достичь этого путем применения мелкой копии в вашем классе, но проблема в том, кто освободит этот ресурс, и в итоге вы реализуете функцию shared_ptr в своем, возможно, небольшом классе!

  • Каждая новая версия C ++ поставляется с новыми возможностями и новыми мощными функциями, поэтому вам следует придерживаться этих библиотек, а не заново изобретать скважину. Если только по какой-то образовательной причине, то можно практиковаться.

  • Если вы посмотрите, вы обнаружите, что реальные программы содержат умные указатели в качестве членов, которые делают ваш класс надежным.

...