我是智能指针的新手,我喜欢使用它们来确保共享对象的安全和强大。。。
我有一个问题:如果我的类在构造函数和析构函数中管理资源,并应用一些经验规则,比如Big 5和Big 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;
};
考虑一下我班的成员做的工作是正确的,所以我可以避免智能指针吗?
我想知道一些场景,当我应该使用智能指针而不是管理类中的资源时。
它们真的是像C++入门书中那样的"哑类"(定义构造函数但不是行为良好的析构函数的类(吗。
您的问题可以读作
如果我在使用的每个类中手动实现智能指针内存所有权的正确语义,我能避免使用智能指针吗?
是,但为什么?当你需要一个动态数组时,你会在每次需要时手工重新实现基本的std::vector
语义吗?我不这么认为。
这是图书馆的目的,避免每次都重新发明轮子。
智能指针的另一个尚未提及的好处是,它们可以让阅读代码的人对该对象的生存期有一个很好的了解。原始指针的问题是(尤其是当代码变得更加复杂时(,很难弄清楚谁负责对对象调用delete,而如果你有一个唯一的指针,我们会立即知道,当指针超出范围时,删除会自动发生。
正如您在书中所读到的:它们解决了原始指针所面临的问题:考虑一下:
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++的每个新版本都有新的功能和新的强大功能,所以你应该坚持使用这些库,而不是重新发明井。如果只是出于某种教育原因,那么练习是可以的。
如果你仔细观察,你会发现真正的程序包含智能指针作为成员,这使你的类变得健壮。