标签: smart-pointers

C++ 0x智能指针比较:不一致,理由是什么?

在C++ 0x(n3126)中,可以比较智能指针,无论是关系还是相等.但是,这样做的方式似乎与我不一致.

例如,shared_ptr定义operator<相当于:

template <typename T, typename U>
bool operator<(const shared_ptr<T>& a, const shared_ptr<T>& b)
{
    return std::less<void*>()(a.get(), b.get());
}
Run Code Online (Sandbox Code Playgroud)

std::less与未指定的vanilla关系指针比较不同,使用提供关于指针值的总排序.

但是,unique_ptr定义相同的运算符:

template <typename T1, typename D1, typename T2, typename D2>
bool operator<(const unique_ptr<T1, D1>& a, const unique_ptr<T2, D2>& b)
{
    return a.get() < b.get();
}
Run Code Online (Sandbox Code Playgroud)

它还以类似的方式定义了其他关系运算符.


为什么改变方法和"完整性"?也就是说,为什么shared_ptr使用std::less,而unique_ptr使用内置的operator<?为什么不shared_ptr提供其他关系运算符,比如unique_ptr

我可以理解这两种选择背后的理由:

  • 关于方法:它代表一个指针,所以只需使用内置指针运算符,而不是它需要在一个关联容器中使用,所以提供总排序(就像一个vanilla指针将使用默认的std::less谓词模板参数获得)
  • 关于完整性:它表示一个指针,因此提供与指针相同的所有比较,而它是一个类类型,只需要比在关联容器中使用的相当,所以只提供该要求

但我不明白为什么选择根据智能指针类型而改变.我错过了什么?


奖金/相关:std::shared_ptr似乎已经跟随boost::shared_ptr,后者省略了"按设计"的其他关系运算符(也是如此 …

c++ smart-pointers std rationale c++11

11
推荐指数
1
解决办法
1177
查看次数

关于使用CComPtr的一些问题(当使用Release()时?我可以返回CComPtr吗?,...)

我为Internet Explorer(BHO)编写附加组件,我正在使用CComPtr智能指针.我想知道:

  1. 我什么时候应该使用CComPtr.Release()函数?

  2. 在这链接它是用来释放浏览器对象.我应该在哪里使用它?在'正常'使用(使用我自己的类)我不需要它.我应该在这种情况下使用它:
    我使用m_spWebBrowser-> get_Document(&spDispDoc)获取文档对象:
    void STDMETHODCALLTYPE CHelloWorldBHO::OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL)
    {
        // Query for the IWebBrowser2 interface.
        CComQIPtr spTempWebBrowser = pDisp;
    
        // Is this event associated with the top-level browser?
        if (spTempWebBrowser && m_spWebBrowser &&
            m_spWebBrowser.IsEqualObject(spTempWebBrowser))
        {
            // Get the current document object from browser...
            CComPtr spDispDoc;
            hr = m_spWebBrowser->get_Document(&spDispDoc);
            if (SUCCEEDED(hr))
            {
                // ...and query for an HTML document.
                CComQIPtr htmlDoc2 = spDispDoc;
                m_spHTMLDocument = spHTMLDoc;
            }
        }
    
    }
    
    我应该像使用m_spWebBrowser一样在SetSite函数中释放spHTMLDocument(就像之前提到的链接一样)?
  3. 我可以安全地从函数返回CComPtr吗?
  4. 我的意思是这样的:
    CComPtr getObjects(CComQIPtr<IHTMLDocument3> …

c++ com bho smart-pointers

11
推荐指数
1
解决办法
1万
查看次数

在C++中实现弱的侵入式指针

弱指针就像智能指针,除了弱指针的引用不会阻止垃圾收集,弱指针必须在使用之前检查它们的有效性.

在我们的项目中(Linderdaum Engine http://www.linderdaum.com)中,我们使用了侵入式指针.为了避免循环引用和孤立孤岛,我们通过以下方式实现了弱入侵指针:

namespace LPtr
{
    clPtr<iObject> GetObjectsGraphPtrWrapper( sEnvironment* Env, iObject* Obj, size_t Generation );
};

/// Intrusive weak smart pointer
template <class T> class clWeakPtr
{
public:
    /// default constructor
    clWeakPtr(): Env( NULL ), FObject( NULL ), FGeneration( 0 ) {}
    explicit clWeakPtr( T* Ptr )
     : Env( Ptr ? Ptr->Env : NULL )
     , FObject( Ptr )
     , FGeneration( Ptr ? Ptr->FGeneration : 0 ) {}
    explicit clWeakPtr( const clPtr<T>& Ptr )
     : Env( Ptr ? …
Run Code Online (Sandbox Code Playgroud)

c++ weak-references smart-pointers

11
推荐指数
1
解决办法
1976
查看次数

unique_ptr的赋值运算符复制由引用存储的删除器.它是一个功能还是一个bug?

当您拥有unique_ptr由引用存储的自定义删除器时,对该案例进行成像:

struct CountingDeleter
{
    void operator()(std::string *p) {
        ++cntr_;
        delete p;
    }

    unsigned long cntr_ = 0;
};

int main()
{
    CountingDeleter d1{}, d2{};

    {
        std::unique_ptr<std::string, CountingDeleter&>
            p1(new std::string{"first"} , d1),
            p2(new std::string{"second"}, d2);

        p1 = std::move(p2); // does d1 = d2 under cover
    }

    std::cout << "d1 " << d1.cntr_ << "\n"; // output: d1 1
    std::cout << "d2 " << d2.cntr_ << "\n"; // output: d2 0
}
Run Code Online (Sandbox Code Playgroud)

这是一个惊喜,我在上面的代码分配具有复制的副作用d2d1.我仔细检查了一下,发现这种行为与[unique.ptr.single.asgn]中的标准一样 …

c++ smart-pointers unique-ptr c++11

11
推荐指数
2
解决办法
599
查看次数

c ++创建shared_ptr到堆栈对象

在我的方法中,创建一个Player对象,如:

Player player(fullName,age);
Run Code Online (Sandbox Code Playgroud)

我的老师给了我们一段带有构造函数的代码,该构造函数将shared_ptr带到了一个玩家对象.

//constructor of the class
SomeClass(const std::shared_ptr<Socket> client, std::shared_ptr<Player> player)
Run Code Online (Sandbox Code Playgroud)

让我们说我们想要调用SomeClass的构造函数并传递我们在堆栈上创建的玩家对象.

从堆栈对象创建shared_ptr是否安全/可能/好?

为了使问题更容易理解,我们假设我们有两个大的代码项目,并且我们想要合并它们,以便从另一个项目中调用一个项目的方法,我们是否应该重写所有文件以使用shared_ptr或独立地堆栈对象(对于那些方法而言)需要连接)或者我们应该只为堆栈对象创建一个shared_ptr.

为什么我不确定结果:

如果创建stackobject的范围结束但仍然使用shared_ptr,反之亦然.

stackobject在超出范围时会被删除,或者它是否仍然存活,因为仍然存在对该对象的引用(尽管在另一个类中)?

shared_ptr超出范围并尝试删除对象,即使stackobject引用它也可以吗?

注意:我知道我可以使用以下内容并传递播放器

shared_ptr<Player> player{ new Player {fullName,age} };
Run Code Online (Sandbox Code Playgroud)

c++ smart-pointers shared-ptr c++11

11
推荐指数
3
解决办法
6163
查看次数

unique_ptr operator =

std::unique_ptr<int> ptr;
ptr = new int[3];                // error
Run Code Online (Sandbox Code Playgroud)
error C2679: binary '=' : no operator found which takes a right-hand operand of type 'int *' (or there is no acceptable conversion)

为什么这不编译?如何将本机指针附加到现有的unique_ptr实例?

c++ smart-pointers visual-studio-2010 c++11

10
推荐指数
1
解决办法
9896
查看次数

C++使用C++ 11分配shared_ptr(std :: shared_ptr):将shared_ptr初始化为临时变量仍然不好吗?

我正在阅读这个答案,作者提到了最佳实践:

避免使用未命名的shared_ptr临时值来保存输入; 要了解为什么这是危险的,请考虑以下示例:

void f(shared_ptr<int>, int); 
int g();

void ok() {
    shared_ptr<int> p(new int(2));
    f(p, g());
}

void bad() {
    f(shared_ptr<int>(new int(2)), g());
}
Run Code Online (Sandbox Code Playgroud)

函数ok遵循字母的准则,而bad构造临时shared_ptr,承认内存泄漏的可能性.由于函数参数是以未指定的顺序计算的,因此可以首先计算new int(2),g()second,如果g抛出异常,我们可能永远不会访问shared_ptr构造函数.<...>

通过使用boost/make_shared.hpp中定义的make_shared或allocate_shared工厂函数,也可以消除上述异常安全问题.这些工厂功能还通过合并分配提供了效率优势.

我想我会开始使用make_shared,但我想知道这一点建议是否仍然适用于C++ 11 shared_ptr.我问,因为我并不完全理解为什么投掷g()会阻止ctor被调用.

c++ pointers smart-pointers shared-ptr c++11

10
推荐指数
1
解决办法
1292
查看次数

std :: vector的不完整类型

当我尝试以下操作时,GCC编译器会抱怨(见下文).class Face需要不完整,因为它包含指向class Element同样包含指针的指针class Face.换句话说,类之间存在循环依赖关系.我该如何解决?

错误:'sizeof'无效应用于不完整类型'Face'

class Face; // needs to be incomplete

class Element
{
    std::vector < std::unique_ptr <Face> > face;
};

class Face
{
    std::vector < std::unique_ptr <Element> > elm;
};
Run Code Online (Sandbox Code Playgroud)

c++ containers smart-pointers incomplete-type

10
推荐指数
1
解决办法
3016
查看次数

是否有推荐的方法来测试智能指针是否为空?

我正在尝试检查a std::shared_ptr是否为空.这样做有什么区别

std::shared_ptr<int> p;
if (!p) { // method 1 }
if (p == nullptr) { // method 2 }
Run Code Online (Sandbox Code Playgroud)

c++ smart-pointers shared-ptr c++11

10
推荐指数
1
解决办法
6487
查看次数

unique_ptr堆和堆栈分配

原始指针可以指向堆栈或堆上分配的对象.

堆分配示例:

// heap allocation
int* rawPtr = new int(100);
std::cout << *rawPtr << std::endl;      // 100
Run Code Online (Sandbox Code Playgroud)

堆栈分配示例:

int i = 100;
int* rawPtr = &i;
std::cout << *rawPtr << std::endl;      // 100
Run Code Online (Sandbox Code Playgroud)

使用auto_ptr示例堆分配:

int* rawPtr = new int(100);
std::unique_ptr<int> uPtr(rawPtr);
std::cout << *uPtr << std::endl;        // 100
Run Code Online (Sandbox Code Playgroud)

使用auto_ptr示例堆栈分配:

int i = 100;
int* rawPtr = &i;
std::unique_ptr<int> uPtr(rawPtr);      // runtime error
Run Code Online (Sandbox Code Playgroud)

是否有"智能指针"用于指向堆上动态创建的对象?对于C++ 11,我们是否应该继续使用原始指针来指向堆栈分配的对象?谢谢.

pointers smart-pointers heap-memory unique-ptr c++11

10
推荐指数
2
解决办法
5324
查看次数