C++ 如果我的类正确地管理了一个资源,那么使用智能poointers有什么意义呢?

C++ 如果我的类正确地管理了一个资源,那么使用智能poointers有什么意义呢?,c++,c++11,smart-pointers,C++,C++11,Smart Pointers,我对智能指针还不熟悉,我喜欢使用它们来实现共享对象的安全性和功能 我有一个问题:如果我的类在其构造函数和析构函数中管理资源,并应用一些经验法则,比如大5和大3。。。我还应该使用智能指针吗?或者我的班级是他们的替代品。因为我已经在C++入门5版中读到智能指针来解决问题,原始指针面临内存泄漏、双重删除指针和访问悬空指针等问题。我的班级可以避免这些问题: class BallGame { public: using Resource = int; BallGa

我对智能指针还不熟悉,我喜欢使用它们来实现共享对象的安全性和功能

我有一个问题:如果我的类在其构造函数和析构函数中管理资源,并应用一些经验法则,比如大5和大3。。。我还应该使用智能指针吗?或者我的班级是他们的替代品。因为我已经在C++入门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;
};
  • 考虑到我们班的成员做了正确的工作,那么我可以避免使用智能指针吗

  • 我想知道一些我应该使用智能指针而不是管理类中的资源的场景

  • >P>它们是否真正适用于“哑类”(定义构造函数但不具有良好行为析构函数的类),如C++入门书中的那样。


      您的问题可以理解为

      如果我在使用的每个类中手动实现智能指针的内存所有权的正确语义,我可以避免使用智能指针吗

      是的,但是为什么呢?当您需要动态数组时,是否每次需要时都手动重新实现基本
      std::vector
      语义?我不这么认为


      这是图书馆的宗旨,避免每次重新发明轮子。

      正如你在你的书中所读到的:它们解决了原始指针所面临的问题:考虑一下:

      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
      
      int*ptr=newint[1024];
      //天哪!忘了释放它,欢迎来到内存泄漏
      std::string*pStr=newstd::string(“Hello”);
      删除pStr;
      //...
      //在程序中的某个时刻,你认为是时候释放已经释放的pStr了(在数百行代码中),然后欢迎来到U.B。
      
      std::cout智能指针的另一个尚未提及的好处是,无论是谁阅读代码,都能对该对象的生命周期有一个合理的了解。使用原始指针的问题是(尤其是当代码变得更加复杂时)很难确定谁负责对对象调用delete,但是如果您有一个唯一的指针,我们会立即知道,当指针超出范围时,删除将自动发生。

      大多数资源都可以由智能指针和自定义删除器处理,避免编写自定义类来处理它们(或者是实现它的一种方式)。既然可以使用规则0,为什么还要使用规则3/5:)谢谢!但是我的类可以有一个
      std::vector
      作为数据成员。你也可以有一个
      std::unique\u ptr
      作为数据成员,我看不出有什么区别。另外请注意:手工管理资源可能非常困难。这不仅仅是“确保在普通构造函数中正确设置并在析构函数中清除”,您通常还希望各种赋值运算符甚至提供基本的异常保证(如果发生异常,则无内存泄漏),更不用说强异常保证了,需要确保移动构造/分配使实例处于合法状态,以便析构函数等使用。正确使用智能指针和其他托管资源通常意味着您甚至不必编写所有这些。是的。你的头号问题不是你预期的bug。如果你有任何生存的希望,你已经消除了所有可以消除的已知风险,并减轻了其余的风险。是那些你没有预见到的东西吸引了你。
      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.