Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么要共享\u ptr<;无效>;不专业?_C++_Pointers - Fatal编程技术网

C++ 为什么要共享\u ptr<;无效>;不专业?

C++ 为什么要共享\u ptr<;无效>;不专业?,c++,pointers,C++,Pointers,shared\u ptr的特殊之处在于,根据定义,它将通过在void*上调用delete来调用未定义的行为 那么,为什么没有抛出编译错误的shared\u ptr专门化呢?如果指针是通过malloc之类的方式创建的,那么可以创建shared\u ptr,其中dtor调用free。这将导致定义的行为 但是,再一次,也许您想要未定义的行为:D,但它在许多情况下都是有效的。考虑以下事项: class T { public: ~T() { std::cout << "~T\n"; }

shared\u ptr
的特殊之处在于,根据定义,它将通过在
void*
上调用
delete
来调用未定义的行为


那么,为什么没有抛出编译错误的
shared\u ptr
专门化呢?

如果指针是通过
malloc
之类的方式创建的,那么可以创建
shared\u ptr
,其中
dtor
调用
free
。这将导致定义的行为


但是,再一次,也许您想要未定义的行为:D

,但它在许多情况下都是有效的。考虑以下事项:

class T
{
public:
    ~T() { std::cout << "~T\n"; }
};

int main()
{
    boost::shared_ptr<void> sp(new T);
}
T类
{
公众:
~T(){std::cout
shared_ptr
的特殊之处在于,根据设计,它可以持有指向任何可转换为
T*
的指针类型的指针,并在不使用UB的情况下使用适当的删除器!这在
shared_ptr p(新派生)
场景中起作用,但也包括
shared_ptr

例如:

#include <boost/shared_ptr.hpp>

struct T {
    T() { std::cout << "T()\n"; }
    ~T() { std::cout << "~T()\n"; }
};


int main() {
    boost::shared_ptr<void> sp(new T);
}
如果您访问,请向下滚动至作业部分,查看演示的内容。有关更多详细信息,请参阅

EDIT正如trinithis所指出的,如果传递到构造函数中的指针类型是
void*
指针,则UB。感谢您指出这一点

shared_ptr可以充当类似于void*的通用对象指针。当shared_ptr实例构造为:

shared_ptr<void> pv(new X);
shared_ptr pv(新X);
如果被销毁,它将通过执行~X正确处理X对象

此属性的使用方式与原始void*用于临时从对象指针中删除类型信息的方式大致相同。共享的\u ptr稍后可以通过使用静态\u pointer\u cast转换回正确的类型

但是怎么做呢?

为什么需要专门化?它不是已经抛出了一个编译器错误吗?@MooingDuck实在无法解释为什么
delete(void*)0,是由C++委员会允许的,或者是一个笑话,实施者很认真。为什么你认为这是不可能的,“好奇的家伙?”并不是所有的委员会成员都死了,没有留下任何笔记。我相信大多数人还活着,而且可能有会议纪要和信件。这不是古代历史。illing致力于研究它可能会确切地告诉我们为什么它是这样。请注意,如果传入构造函数的指针类型是
void*
指针,这就是UB。即使传入的指针类型是
void*
,您还不能通过使用双参数构造函数来避免未定义的行为吗传递一个自定义的删除程序,该删除程序除了调用
delete
?这个答案是否只适用于
boost::shared_ptr
std::shared_ptr
?我找不到合适的引用。@Mark Ransom:据我所知
std::shared_ptr
具有相同的功能。@Rob:当然,但这仍然需要一个特殊的引用
std::shared_ptr
的化消除了一个参数ctor。有一个
get_deleter
,但没有
set_deleter
,因此如果在构造过程中不传递deleter,将导致以后出现未定义的行为。
shared_ptr<void> pv(new X);