标签: smart-pointers

智能指针列表 - 管理对象生命周期和指针有效性

我有一个智能指针列表,其中每个指针都指向一个单独的实体类。

std::list<std::unique_ptr<Entity>> m_entities;

我希望构造函数能够处理每个指针对 std::list 类的分配,因为它是由类实例化的代码“自动”处理的。然而,如果这个设计很糟糕,那么我会欢迎更好的选择,因为它只对来自 C# 背景的我有意义。

Entity::Entity(Game &game) 
    : m_game(game),             
    m_id(m_game.g_idGenerator->generateNewID())             
{
    m_game.m_entities.push_back(std::unique_ptr<Entity>(this));
}
Run Code Online (Sandbox Code Playgroud)

我使用此方法遇到的主要问题是实体类的生命周期不受实体类管理。

例如,如果我在堆栈上分配一个实体类,它将在离开分配它的方法后调用实体析构函数,并且指针将不再有效。

因此,我考虑了另一种选择:创建智能指针,将实体类分配到堆,然后将指针显式添加到列表中。

std::unique_ptr<Entity> b(new Entity(*this));
m_entities.push_back(b);   // ERROR
Run Code Online (Sandbox Code Playgroud)

这会产生以下错误

error C2664: 'void std::list<_Ty>::push_back(_Ty &&)' : cannot convert parameter 1 from 'std::unique_ptr<_Ty>' to 'std::unique_ptr<_Ty> &&'
Run Code Online (Sandbox Code Playgroud)

将每个指针分配到列表的最佳方法是什么?基于构造函数的版本是否可能?

我目前认为智能指针列表应该处理每个实体类的生命周期,并且在构造函数中分配指针不是一个好的设计选择。在这种情况下,我可能应该创建一个 CreateEntity 方法,将指针添加到列表中,而不是让构造函数处理它。这是否更好?

在阅读了此处此处此处(场外)发现的问题后,我考虑了哪种类型的智能指针适合此操作。根据我到目前为止所读到的内容,很难得到准确的答案,因为它们都提供了一些相互矛盾的建议。

c++ constructor list smart-pointers c++11

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

了解 C++ 使用 const 参数创建共享指针

我在某处找到了这段代码:

boost::shared_ptr<const Foo> pFoo = boost::make_shared<const Foo>();
Run Code Online (Sandbox Code Playgroud)

这里关键字的目的是什么const

c++ boost smart-pointers c++11

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

使用智能指针和继承构造函数的前向声明

根据这个问题,如果所有构造函数和析构函数都不是内联的(则需要完全定义的类型),则可以转发声明智能指针。当未提供析构函数时,编译器将声明一个析构函数并提供内联定义,该定义随后要求标头中完全已知智能指针中的类型。这同样适用于默认构造函数。

然而,我发现它也适用于继承的构造函数,这对我来说有点令人困惑。考虑:

class Base
{
public:
    Base(); //defined in cpp
};

class SomeClass;

class Derived : public Base
{
    using Base::Base;
    ~Derived(); //defined in cpp

    std::unique_ptr<SomeClass> ptr;
};
Run Code Online (Sandbox Code Playgroud)

Derived除非显式声明构造函数并仅在源文件中定义,否则不会编译。为什么?构造函数Base不是内联的,据我所知,using 指令应该以与其他成员类似的方式导致构造函数的“继承”。或者编译器是否将其解释为“为我声明与中相同的构造函数Base并内联定义它们”?

c++ constructor smart-pointers forward-declaration c++11

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

Shared_ptr 自定义删除器

我需要为 shared_ptr 做自定义删除器。我知道这可以通过类似的方式完成:

std::shared_ptr<SDL_Surface>(Surf_return_f(), MyDeleter);
Run Code Online (Sandbox Code Playgroud)

但我想按照我的 unique_ptr 自定义删除器的风格制作它们:

struct SDL_Surface_Deleter {
    void operator()(SDL_Surface* surface) {
        SDL_FreeSurface(surface);
    }
};

using SDL_Surface_ptr = std::unique_ptr<SDL_Surface, SDL_Surface_Deleter>;
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点?

c++ sdl smart-pointers c++11

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

如何从原始 C 堆内存指针初始化 unique_ptr?

我正在使用一个函数(它是库的一部分),它返回一个uint8_t*指向已在堆上分配并保存图像像素数据的内存的原始指针。这个函数的调用者负责调用free指针。

我调用此函数的代码有许多提前终止的分支,因此我需要free(buffer)在许多点调用。我认为最好将缓冲区包装在 a 中,unique_ptr以便当它超出范围时,内存会自动释放。

我怎样才能做到这一点?

作为参考,函数 decleration 看起来像这样:(uint8_t* getFrame()我已经知道图像的宽度、高度和 num 通道以及缓冲区的长度);

c++ smart-pointers heap-memory unique-ptr raw-pointer

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

尝试使用智能指针时抛出异常

不久前,我正在练习设计模式,最近,我尝试实现工厂方法模式。我的朋友告诉我应该总是使用智能指针,所以我已经尝试过了,但是我的编译器抛出了一个名为“访问冲突”的异常。我究竟做错了什么?有一个名为“Shape”的接口,从它继承了三个类,Client 类和 main 函数。我试图用智能指针做所有事情,但我有点不确定,如果我做得对。

#include <iostream>
#include <memory>

class Shape
{
public:
    virtual void printShape() = 0;
    static std::shared_ptr<Shape> Create(int num);
};

class Triangle : public Shape
{
public:
    virtual void printShape()
    {
        std::cout << "This is Triangle. \n";
    }
};

class Circle : public Shape
{
public:
    virtual void printShape()
    {
        std::cout << "This is Circle. \n";
    }
};

class Rectangle : public Shape
{
public:
    virtual void printShape()
    {
        std::cout << "This is Rectangle. \n";
    }
};

class …
Run Code Online (Sandbox Code Playgroud)

c++ design-patterns exception smart-pointers

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

使用 std::unique_ptr 创建对象数组

我目前正在学习智能指针并尝试执行以下操作:

#include <memory>
#include <string>

int main() {
    std::unique_ptr<std::string[]> str_array(new std::string[5]);
    for (int i = 0; i < 5; i++) {
        std::getline(std::cin, str_array.get()[i]);
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

此代码只是将 5 个std::string对象扫描到一个数组中。但是,调试器显示没有为 5 个对象保留内存:

调试器

我究竟做错了什么?

c++ arrays smart-pointers

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

重新分配 std::unique_ptr 时是否释放内存?

鉴于以下情况:

{
    std::unique_ptr<char[]> foo;
    foo = std::make_unique<char[]>(100);
    foo = std::make_unique<char[]>(200);
}
Run Code Online (Sandbox Code Playgroud)

在第二次调用中重新分配 foo 时,第一次调用 make_unique 时分配的内存是否被释放?

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

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

指向派生对象的基类型指针的 make_unique 的语法是什么?

考虑以下基类和派生类。

class base
{
public:
    int i{9};
    virtual void func()
    {
        cout << "base" << endl;
    }
    virtual ~base()
    {

    }
};

class derived : public base
{
public:
    int i{4};
    void func()
    {
        cout << "derived" << endl;
    }

};
Run Code Online (Sandbox Code Playgroud)

我想创建unique_ptrbase类型derived对象。我知道我能做到

std::unique_ptr<base> ptr{new derived};

但是当我这样做的时候

auto ptr = std::make_unique<base>(derived{});
ptr->func();
Run Code Online (Sandbox Code Playgroud)

这会打印base,这不是我的预期行为。std::make_unique在这种情况下使用的正确方法是什么?另外,为什么auto ptr = std::make_unique<base>(derived{})呢?

c++ smart-pointers

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

为什么在使用 unique_ptr 时没有调用析构函数?

在这里,我正在创建动态分配的 S 对象数组,我希望它们被 unique_ptr 销毁,这不会发生,我收到此错误

命令由信号 11 终止

这意味着程序访问了它不应该访问的内存。

#include <iostream>
#include <memory>

class S{
    public:
        S(){std::cout<<"Constructor\n";}
        ~S(){std::cout<<"Destructor\n";}
};

int main() {
    S* arr=new S[4];
    {
        using namespace std;
        unique_ptr<S> ptr=unique_ptr<S>(arr);
    }
}
Run Code Online (Sandbox Code Playgroud)

c++ smart-pointers unique-ptr

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