标签: smart-pointers

为什么 std::unique_ptr 的 get() 获取的原始指针无法删除对象以及它是如何实现的

正如下面的代码所示,我尝试通过从 unique_ptr 获取的原始指针来删除该对象。但是,正如输出所示,编译器报告了错误。然而,对于原始指针,我们可以这样做int *p1 = new int{100}; int* p2 = p1; delete p2;

此外,我认为 unique_ptr 通过移动语义来维持其所有权。由于unique_ptr的get()函数返回的是原始指针,那么unique_ptr如何仍然拥有该对象的所有权呢?同时,为什么原始指针没有获得所有权。同时,我很困惑这是如何实现的。谢谢。

#include <iostream>
#include <memory>

int main(int argc, char const *argv[])
{
    std::unique_ptr<int> newPtr = std::make_unique<int>(1234);
    std::cout << *newPtr << std::endl;
    int* rawInt = newPtr.get();
    *rawInt = 200;
    delete rawInt;
    rawInt = nullptr;
    std::cout << *newPtr << std::endl; 
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

该代码在 MacO 上执行,输出为:

输出

c++ smart-pointers unique-ptr

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

当unique_ptr被销毁时,如何检索pclose的返回值?

正如 @user17732522 指出的那样, 的删除器std::unique_ptr应该可以用一个指针作为参数来调用。

如何检索pcloseunique_ptr 被销毁时的返回值?

代码片段无法编译,

#include<memory>
#include<iostream>
#include<string>
#include<cstdio>

int ExecCmd(const std::string& cmd, std::string& output)
{
    int ret = 0;

    {
        std::unique_ptr<FILE, void(*)(FILE*, int*)> pipe(popen(cmd.c_str(), "r"), [](FILE* file, int* ret_ptr){
                              if(NULL==file)
                              {
                                  *ret_ptr = -1;
                              } 
                              else 
                              {
                                  *ret_ptr = pclose(file);
                              }
                         });
    }

    return ret;
}

int main()
{

}
Run Code Online (Sandbox Code Playgroud)

而下面的代码片段可以编译。

#include<memory>
#include<iostream>
#include<string>
#include<cstdio>

int ExecCmd(const std::string& cmd, std::string& output)
{
    int ret = 0;

    { …
Run Code Online (Sandbox Code Playgroud)

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

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

为什么即使在分配给该指针的 unique_ptr 超出范围后该指针仍然存在?

我最近开始学习 C++ 中的智能指针和移动语义。但我不明白为什么这段代码有效。我有这样的代码:

#include <iostream>
#include <memory>

using namespace std;

class Test
{
public:
    Test() 
    {
        cout << "Object created" << endl;
    }

    void testMethod()
    {
        cout << "Object existing" << endl;
    }

    ~Test() 
    {
        cout << "Object destroyed" << endl;
    }
};

int main(int argc, char *argv[])
{
    Test* testPtr = new Test{};
    {
        unique_ptr<Test> testSmartPtr(testPtr);
    }
    testPtr->testMethod();
    
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我的输出是:

Object created
Object destroyed
Object existing
Run Code Online (Sandbox Code Playgroud)

为什么行testPtr->testMethod()有效?如果指针是左值,unique_ptr 不会在销毁时删除分配给它的指针吗?

编辑:我从评论中了解到,此方法不会检查指针是否存在。如果是这样,有没有办法检查指针是否有效?

编辑:我了解到我不应该对无效指针做任何事情。感谢您的所有回答和评论。

编辑:即使这个代码也有效:

#include <iostream>
#include <memory> …
Run Code Online (Sandbox Code Playgroud)

c++ pointers memory-management smart-pointers unique-ptr

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

std::vector&lt;std::unique_ptr&lt;UnimplementType&gt;&gt; 编译错误

我的代码出现错误。\n我在类 <RenderPass> 中使用前向声明,std::unique_ptr<RenderPass> 工作良好。但是 std::vector<std::unique_ptr<RenderPass>> 会导致编译错误。\n以前有人遇到过这种情况吗?谢谢\xef\xbc\x81

\n
class RenderPass;\n\nclass RenderSystem final\n{\npublic:\n    RenderSystem() = default;\n    ~RenderSystem();\n\nprivate:\n    std::unique_ptr<RenderPass> c {} // work;\n    std::vector<std::unique_ptr<RenderPass>> m_render_passes {} // compile error:  error C2338: static_assert failed: 'can't delete an incomplete type';\n
Run Code Online (Sandbox Code Playgroud)\n

c++ memory smart-pointers

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

为什么不调用复制构造函数?

#include <iostream>
#include <memory>

using namespace std;

class Init {
private:
    int x;
public:
    Init(int y) {
        x = y;
        cout << "default constructor called" << endl;
        
    }
    
    Init(std::shared_ptr<Init> z) {
        this->x = z->x;
        cout << "copy constructor called" << endl;
    }
};

int main()
{
    int k = 5;
    std::shared_ptr<Init> a = std::make_shared<Init>(k);
    std::shared_ptr<Init> b(a);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我的期望是同时调用默认构造函数和复制构造函数,但只调用默认构造函数。可能是什么问题?

输出是: 默认构造函数称为

c++ smart-pointers copy-constructor shared-ptr default-constructor

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

如何在表达式中触发 std::shared_ptr 的 bool 运算符(即 `bool is_empty = shared_ptr1 &amp;&amp; shared_ptr2;` )?

鉴于cur_front_rescur_back_res都是shared_ptr, std::shared_ptr 的 bool 运算符如何在表达式(即bool is_empty = cur_front_res && cur_back_res;)中触发?

仅仅因为如果操作数(即 before和 after )不是 bool 类型,&&总是会导致内置转换?&&&&

下面的代码片段确实有效

#include <iostream>
#include <memory>

int main() {
    std::shared_ptr<int> cur_front_res; // Empty shared_ptr
    std::shared_ptr<int> cur_back_res(new int(42)); // Shared_ptr pointing to an int

    bool is_empty = cur_front_res && cur_back_res;

    if (is_empty) {
        std::cout << "Both cur_front_res and cur_back_res are not empty" << std::endl;
    } else {
        std::cout << "Either cur_front_res or cur_back_res is empty" …
Run Code Online (Sandbox Code Playgroud)

c++ smart-pointers shared-ptr c++14

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

具有预定义最大使用次数的共享指针

上下文:我有一个队列,支持来自两个不同(/或非)线程的单读/单写,为了强制执行此行为,即一次单读/单写,我需要限制拥有的线程数量队列一次为2(作者已经拥有该队列),我当时正在考虑为队列创建一个shared_ptr,并将编译时已知的最大引用计数设置为2。因此我的问题如下。

问题:有没有一种方法可以实现unique_pointer具有编译时已知的最大引用计数的共享指针(可能使用 's)?我的情况是max_ref_count = 2,超过引用计数限制 = 2 应该是编译时错误。

const auto p    = std::make_shared<2, double>(2159); //works fine
const auto q    = p; // works fine
const auto err1 = p; // does not compile
const auto err2 = q; // does not compile
Run Code Online (Sandbox Code Playgroud)

c++ smart-pointers shared-ptr unique-ptr

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

提升智能指针:我能以更简洁的方式表达吗?

今天我一直在使用Boost :: shared_ptr,我有一个问题.

vector<shared_ptr<KlasaA> > vec;
vec.push_back(shared_ptr<KlasaA>(new KlasaB));
vec.push_back(shared_ptr<KlasaA>(new KlasaC));
vec.push_back(shared_ptr<KlasaA>(new KlasaC));
vec.push_back(shared_ptr<KlasaA>(new KlasaA));

for (vector<shared_ptr<KlasaA> >::const_iterator c_it = vec.begin();
    c_it != vec.end(); ++c_it)
{
    cout << c_it->get()->foo(10) << endl;
}
Run Code Online (Sandbox Code Playgroud)

上面的循环遍历向量并以多态方式调用foo(10).

我的问题是:

能够...

for (vector<shared_ptr<KlasaA> >::const_iterator c_it = vec.begin();
    c_it != vec.end(); ++c_it)
Run Code Online (Sandbox Code Playgroud)

cout << c_it->get()->foo(10) << endl;
Run Code Online (Sandbox Code Playgroud)

以更简洁的方式表达?提前致谢.

c++ boost smart-pointers shared-ptr

0
推荐指数
1
解决办法
237
查看次数

thread_local std :: unique_ptr释放不调用析构函数

为什么不在此代码中调用析构函数:

#include <iostream>
#include <thread>
#include <memory>

class base {
    public:
        base() {
            std::cout << "base()" << std::endl;
        }
        virtual ~base() {
            std::cout << "~base()" << std::endl;
        }
        base(const base&) = delete;
        base(base&&) = delete;
        base& operator=(const base&) = delete;
        base& operator=(base&&) = delete;
};

class derived final : public base {
    public:
        derived() {
            std::cout << "derived()" << std::endl;
        }
        virtual ~derived() {
            std::cout << "~derived()" << std::endl;
        }
};


void foo() {
    static thread_local std::unique_ptr<base> ptr; …
Run Code Online (Sandbox Code Playgroud)

c++ smart-pointers thread-local-storage c++11

0
推荐指数
1
解决办法
1368
查看次数

如何正确删除这些指针?

这是我的分配:

for (int i = 0; i < numCols; i++)
{
    columnNameLen = new SQLSMALLINT *[numCols];
    columnDataType = new SQLSMALLINT *[numCols];
    columnDataSize = new SQLULEN *[numCols];
    columnDataDigits = new SQLSMALLINT *[numCols];
    columnDataNullable = new SQLSMALLINT *[numCols];
    columnData = new SQLWCHAR *[numCols];
    columnDataLen = new SQLLEN *[numCols];
    columnName = new SQLWCHAR *[numCols];
}

for (int i = 0; i < numCols; i++)
{
    columnNameLen[i] = new SQLSMALLINT;
    columnDataType[i] = new SQLSMALLINT;
    columnDataSize[i] = new SQLULEN;
    columnDataDigits[i] = new SQLSMALLINT;
    columnDataNullable[i] = …
Run Code Online (Sandbox Code Playgroud)

c++ pointers smart-pointers c++11

0
推荐指数
2
解决办法
102
查看次数