我有一个智能指针列表,其中每个指针都指向一个单独的实体类。
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 方法,将指针添加到列表中,而不是让构造函数处理它。这是否更好?
在阅读了此处、此处和此处(场外)发现的问题后,我考虑了哪种类型的智能指针适合此操作。根据我到目前为止所读到的内容,很难得到准确的答案,因为它们都提供了一些相互矛盾的建议。
我在某处找到了这段代码:
boost::shared_ptr<const Foo> pFoo = boost::make_shared<const Foo>();
Run Code Online (Sandbox Code Playgroud)
这里关键字的目的是什么const?
根据这个问题,如果所有构造函数和析构函数都不是内联的(则需要完全定义的类型),则可以转发声明智能指针。当未提供析构函数时,编译器将声明一个析构函数并提供内联定义,该定义随后要求标头中完全已知智能指针中的类型。这同样适用于默认构造函数。
然而,我发现它也适用于继承的构造函数,这对我来说有点令人困惑。考虑:
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并内联定义它们”?
我需要为 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)
有没有办法做到这一点?
我正在使用一个函数(它是库的一部分),它返回一个uint8_t*指向已在堆上分配并保存图像像素数据的内存的原始指针。这个函数的调用者负责调用free指针。
我调用此函数的代码有许多提前终止的分支,因此我需要free(buffer)在许多点调用。我认为最好将缓冲区包装在 a 中,unique_ptr以便当它超出范围时,内存会自动释放。
我怎样才能做到这一点?
作为参考,函数 decleration 看起来像这样:(uint8_t* getFrame()我已经知道图像的宽度、高度和 num 通道以及缓冲区的长度);
不久前,我正在练习设计模式,最近,我尝试实现工厂方法模式。我的朋友告诉我应该总是使用智能指针,所以我已经尝试过了,但是我的编译器抛出了一个名为“访问冲突”的异常。我究竟做错了什么?有一个名为“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) 我目前正在学习智能指针并尝试执行以下操作:
#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 个对象保留内存:
我究竟做错了什么?
鉴于以下情况:
{
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 时分配的内存是否被释放?
考虑以下基类和派生类。
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_ptr的base类型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{})呢?
在这里,我正在创建动态分配的 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++ ×10
smart-pointers ×10
c++11 ×4
unique-ptr ×3
constructor ×2
arrays ×1
boost ×1
exception ×1
heap-memory ×1
list ×1
memory ×1
memory-leaks ×1
raw-pointer ×1
sdl ×1