在C ++ 11/14中是否有任何理由仍然使用原始指针(对于托管资源)?
类中的资源成员变量是否应该保存在自己的智能指针中,以便自动RAII而不需要在析构函数中进行清理?
智能指针的实现是否表明这样做没有开销?
答案 0 :(得分:4)
还有任何理由仍然使用原始指针(对于托管 资源)在C ++ 11/14中?
我认为通过"托管资源"你的意思是拥有资源"。
是的,有理由:
类中的资源成员变量是否应该保存在自己的智能中 自动RAII的指针,无需在析构函数中进行清理?
在最好的情况下,资源成员变量应该只是成员而不是明显的指针,甚至不是智能指针。聪明的指针是一个桥梁"代码之间操纵原始指针和纯RAII风格。如果您完全控制某些代码及其新代码,则可以完全避免在界面中使用智能指针。也许你会在你的实现中需要它们。请记住,没有实际的规则,只有您可能会导致的建议
智能指针的实现是否内联没有 这样做的开销呢?
标准智能指针的实现尽可能高效,因此大多数代码都是内联的。但是,它们并不总是免费的,这取决于它们实际上做了什么。例如,在几乎所有情况下,unique_ptr都只是一个原始指针,只需在其周围进行额外的检查即可。所以它是免费的"。另一方面,shared_ptr必须维护一个计数器,其中有多少其他shared_ptr引用同一个对象。该计数器可以在几个执行shared_ptr副本的线程上更改,因此它必须是原子的。更改原子计数器的值并不总是免费的,您应该始终假设复制原始指针的成本更高。
所以"它取决于"。
只需:
从用户的角度来看,您最终会得到的代码似乎无法操纵指针。如果您遵循这些规则有多层代码,则代码将更易于遵循并且易于维护。
来自When to use references vs. pointers
的相关说明在你不能做之前避免使用指针。
另请注意,Sean Parents在他最近的会谈中也认为智能指针是原始指针。它们确实可以封装为与被操纵的实际概念相对应的值 - 语义类型的实现细节。另外在实现中使用类型擦除技术但从未将它们暴露给用户有助于某些库构造的可扩展性。
答案 1 :(得分:0)
这取决于。如果对象是由另一个对象完全拥有,构造和销毁的,那么在另一个对象中使用std::unique_ptr
是一个很好的例子。如果你有一个拥有几个这样的对象的对象,所有这些对象都是在构造函数中动态分配的,那么你必须做点什么;如果通常的智能指针的语义不合适(通常是这种情况),那么你必须发明一些东西:例如,在图形的情况下,你可以将根指针放入一个基类(将其初始化为null),并让基类的析构函数从根开始清理图形。
当然,除非您的类具有某种动态结构(如图形),否则您可能会问自己为什么要使用动态分配。有一些特殊情况(例如,拥有的对象是多态的,其实际类型取决于构造函数的参数),但根据我的经验,它们并不常见。实际上,在很多情况下,智能指针可以在对象中使用,更不应该使用。
答案 2 :(得分:0)