Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.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++ 什么是boost';s shared_ptr(shared_ptr<;Y>;const&;r,T*p)用于?_C++_Boost_Shared Ptr_Smart Pointers - Fatal编程技术网

C++ 什么是boost';s shared_ptr(shared_ptr<;Y>;const&;r,T*p)用于?

C++ 什么是boost';s shared_ptr(shared_ptr<;Y>;const&;r,T*p)用于?,c++,boost,shared-ptr,smart-pointers,C++,Boost,Shared Ptr,Smart Pointers,boost::shared_ptr有一个不寻常的构造函数 template<class Y> shared_ptr(shared_ptr<Y> const & r, T * p); std::shared_ptr<T> aPtr( any->getReferenceCounter(), //share same ref counter static_cast<T*>(any->getPtr())

boost::shared_ptr
有一个不寻常的构造函数

template<class Y> shared_ptr(shared_ptr<Y> const & r, T * p);
std::shared_ptr<T> aPtr( any->getReferenceCounter(), //share same ref counter 
               static_cast<T*>(any->getPtr()) ); //potentially unsafe cast!
你会得到这个:

0x8c66008
0x8c66030
2
2
请注意,指针是分开的,但它们都声称
use\u count
为2(因为它们共享同一对象的所有权)

因此,只要
x
y
存在,由
x
拥有的
int
就会存在。如果我理解的文档是正确的,那么第二个
int
永远不会被破坏。我已经通过以下测试程序确认了这一点:

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

int main() {
    boost::shared_ptr<T> x(new T);
    boost::shared_ptr<T> y(x, new T);

    std::cout << x.get() << std::endl;
    std::cout << y.get() << std::endl;

    std::cout << x.use_count() << std::endl;
    std::cout << y.use_count() << std::endl;
}

所以。。。这种不寻常的构造共享一个指针的所有权,但在使用时与另一个指针(它不拥有)的行为类似。

当您想要共享一个类成员且该类的实例已经是共享的\u ptr时,它很有用,如下所示:

struct A
{
  int *B; // managed inside A
};

shared_ptr<A>   a( new A );
shared_ptr<int> b( a, a->B );
结构A { int*B;//在内部管理 }; 共享ptr a(新a); 共享ptr b(a,a->b);
他们共享使用计数和其他内容。这是对内存使用的优化。

您可能有一个指向某个驱动程序的指针或一个较低级别api的数据结构,该数据结构可能通过其较低级别api或其他方式分配额外的数据。在这种情况下,可能需要增加使用计数,但如果第一个指针拥有其他数据指针,则返回附加数据。

要展开并回答,此
共享\u ptr
的“别名”描述来自WG21论文:

III.别名支持

高级用户通常需要 能够创建
共享\u ptr
与共享所有权的实例
p
另一个(主控)
共享\u ptr
q
但是 指向不是基准的对象 属于
*q
<代码>*p可以是成员或 例如,
*q
的元素。这 该节提出了一项补充建议 可用于此操作的构造函数 目的

这有一个有趣的副作用 表达能力的提高是什么 现在可以使用
*\u指针\u cast
函数 可以在用户代码中实现。这个
make_shared
显示工厂功能 本文档后面的内容也可以是 仅使用公共资源实现 通过 别名构造函数

影响:

此功能扩展了的接口
以向后兼容的方式共享\u ptr
增加其表现力的方式 权力,因此是强有力的 建议添加到C++0x 标准它没有引入源代码和源代码 二进制兼容性问题

建议文本:

添加到
共享\u ptr
[util.smartptr.shared]以下内容 建造商:

template shared_ptr(共享_ptr const&r,T*p);
将以下内容添加到 [util.smartptr.shared.const]:

template shared_ptr(共享_ptr const&r,T*p);
效果:构造一个
shared_ptr
实例,该实例存储
p
并与
r
共享所有权

后置条件:
get()

他:没什么

[注:为避免指针悬空,用户 必须确保
p
至少保持有效 直到
r
的所有权组被销毁。--结束注释。]

[注意:此构造函数允许创建空的
共享\u ptr
具有非空存储指针的实例。--结束说明。]


您还可以使用它来保持动态强制转换指针,即:

class A {};
class B: public A {};

shared_ptr<A> a(new B);
shared_ptr<B> b(a, dynamic_cast<B*>(a.get()));
A类{};
B类:公共A{};
共享ptr a(新B);
共享(a,动态(a.get());
用于“
共享\u ptr b(a,动态\u cast(a.get());

我认为这不是使用智能指针的推荐方式

执行此类型转换的建议方法应为:

shared_ptr<B> b(a);
shared_ptr b(a);
因为在Boost文档中提到:

共享\u ptr
可以隐式 只要T* 可以隐式转换为U*。在里面 具体而言,
shared\u ptr
是 隐式转换为
共享\u ptr const
, 至
共享\U ptr
,其中U为 T的可接近底座,以及
共享\u ptr

除此之外,我们还有动态指针\U cast
它可以直接在智能指针对象上进行转换,这两种方法都比手动转换原始指针方式安全得多。

我在我的小库中使用了shared_ptr的别名构造函数:

(只是我的简单IoC容器)

关键是,因为我需要从多态类(不知道类型)返回一个已知类型的共享\u ptr。我无法将共享的\u ptr隐式转换为我需要的类型

在文件“”(第72-99行)中,您可以看到IAnyShared类型的操作

别名构造函数创建共享的_ptr,它不会删除它们实际指向的指针,但它们仍然会增加原始对象的引用计数器,这是非常有用的

基本上,您可以使用别名构造函数创建指向任何对象的指针,并将其作为引用计数器

//my class
std::shared_ptr<T> ist;
int a; //dummy variable. I need its adress

virtual std::shared_ptr<int> getReferenceCounter(){
    return std::shared_ptr<int>(ist,&a); //not intended for dereferencing
}

virtual void* getPtr(); //return raw pointer to T
//我的类
std::共享的ptr列表;
INTA//虚拟变量。我需要它的地址
虚拟std::shared_ptr getReferenceCounter(){
return std::shared_ptr(ist,&a);//不用于解引用
}
虚拟void*getPtr()//将原始指针返回到T
现在我们有了“一个引用计数器”和一个指向距离T的指针,足够的数据用别名构造函数创建一些东西

template<class Y> shared_ptr(shared_ptr<Y> const & r, T * p);
std::shared_ptr<T> aPtr( any->getReferenceCounter(), //share same ref counter 
               static_cast<T*>(any->getPtr()) ); //potentially unsafe cast!
std::shared\u ptr aPtr(any->getReferenceCounter(),//共享相同的ref计数器
//my class
std::shared_ptr<T> ist;
int a; //dummy variable. I need its adress

virtual std::shared_ptr<int> getReferenceCounter(){
    return std::shared_ptr<int>(ist,&a); //not intended for dereferencing
}

virtual void* getPtr(); //return raw pointer to T
std::shared_ptr<T> aPtr( any->getReferenceCounter(), //share same ref counter 
               static_cast<T*>(any->getPtr()) ); //potentially unsafe cast!