我有一个对象,它同时定义了复制构造函数和赋值运算符.它包含在共享指针中.
我想创建另一个共享指针,其中包含原始共享指针的副本(即指向新内存位置的新共享指针,但是,它与原始对象具有相同的数据).
谢谢你的帮助.
关于智能指针和内存分配我处于两难境地.
在我的智能指针类中,我通过引擎中的内存模块拥有自己的分配内存方式.
template <class T>
class Object
{
public:
inline Object()
{
Init();
if (mEngine)
{
mObj = (T*) mEngine->GetMemoryManager()->Allocate(sizeof(T));
mRefCount = 1;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,当我想要Destroy()我的引擎时,我想要释放所有内存.这首先是因为我想清理与我的引擎相关的所有内存,还因为清理mObj依赖于我的内存管理器,因为它可能使用例如内存池来分配/释放内存,并且删除该内存管理器将导致不可分配的记忆.
那么我是否用聪明的指针射击自己?有没有一种聪明的方法来解决这个问题?
c++ memory-leaks memory-management smart-pointers reference-counting

我写了两个类头文件.在包含两个标题之前,项目已成功构建.但是在将它们包含在main.cpp之后,如附图中所示,它在构建时受到了抱怨
12:54:13: Starting: "/usr/bin/make"
g++ -c -pipe -g -std=c++0x -Wall -W -fPIE -DQT_QML_DEBUG -DQT_DECLARATIVE_DEBUG -I/usr/share/qt5/mkspecs/linux-g++ -I../CPP_Primer_ch2 -I. -o main.o ../CPP_Primer_ch2/main.cpp
In file included from ../CPP_Primer_ch2/wy_StrBlob.h:19:0,
from ../CPP_Primer_ch2/main.cpp:9:
../CPP_Primer_ch2/wy_StrBlobPtr.h:30:30: error: expected ')' before '&' token
make: *** [main.o] Error 1
12:54:15: The process "/usr/bin/make" exited with code 2.
Error while building/deploying project CPP_Primer_ch2 (kit: Desktop)
When executing step 'Make'
Run Code Online (Sandbox Code Playgroud)
下面是引用的wy_StrBlobPtr.h的代码error: expected ')' before '&' token.
#ifndef WY_STRBLOBPTR_H
#define WY_STRBLOBPTR_H
#include <string>
#include <vector>
#include <memory>
#include <wy_StrBlob.h>
#include <stdexcept> …Run Code Online (Sandbox Code Playgroud) 我试图找出何时使用移动语义以及何时使用复制构造函数和赋值运算符作为经验法则.你的类中使用的指针类型(如果有的话)似乎受到这个答案的影响,所以我已经包含了这个.
没有指针 - 基于这个答案,如果你有一个包含int和string等基本类型的POD类,则不需要编写自定义移动或复制构造函数和运算符.
unique-ptr - 基于这个答案,当使用移动语义时,unique_ptr比shared_ptr更合适,因为资源只能有一个unique_ptr.
shared_ptr - 同样,如果使用复制语义,shared_ptr似乎还有很长的路要走.可以有多个对象副本,因此拥有一个指向资源的共享指针对我来说很有意义.但是,unique_ptr通常优先于shared_ptr,因此如果可以,请避免使用此选项.
但:
我一直在阅读智能指针,最近在课堂上我的TA说我们永远不应该使用原始指针.现在,我已经在网上做了很多阅读,并在这个网站上查看了不同的问题,但我仍然对智能指针的某些方面感到困惑.我的问题是:如果我希望在我的程序中使用它,我会使用哪个智能指针?我会展示一些代码.
所以我有一个基本的Application类,它从类AI中声明对象的声明.注意:出于测试原因,我有两个不同的智能指针,一个是唯一的,另一个是共享的.
// Application class in Application.h
class Application
{
public:
Application(){}
~Application(){}
//... additional non-important variables and such
unique_ptr<AI> *u_AI; // AI object using a unique pointer
shared_ptr<AI> *s_AI; // AI object using a shared pointer
//... additional non-important variables and such
void init();
void update();
};
// AI class in AI.h
class AI
{
public:
AI(){}
~AI(){}
bool isGoingFirst;
};
Run Code Online (Sandbox Code Playgroud)
在Application init函数中,我想创建AI对象,然后我想在更新函数中使用它.我不确定我是否正确地声明我的指针,但我知道它编译的事实,它适用于在init函数中分配和打印数据.更多代码如下.
void Application::init()
{
//.. other initialization's.
std::shared_ptr<AI> temp(new AI());
sh_AI = &temp;
sh_AI->isGoingFirst = true;
//.. …Run Code Online (Sandbox Code Playgroud) 我在阅读C++ primer plus中的智能指针模板类时发现了这样的问题.这本书给出了一个如何实现auto_ptr类的例子,像这样,
template<class X> class auto_ptr {
public:
explicit auto_ptr(X* p = 0) throw();
...};
Run Code Online (Sandbox Code Playgroud)
构造函数结束时的throw()意味着此构造函数不会抛出异常.我知道这已被弃用,但我不知道为什么它需要禁用它的异常抛出.
我在C++ 11中有一个只有一个所有者的对象.但是,其他对象可以保存weak_ptr到此对象.这样,我可以在使用之前测试对象是否仍然存在.
现在,所有者拥有一个shared_ptr对象,其所有者的计数始终为1.
如何确保不允许任何人复制此内容shared_ptr?
我不能使用a,unique_ptr因为显然C++ 11不允许使用weak_ptra unique_ptr.
编辑:谢谢你的回复!
所有程序都在一个线程上运行.主要拥有一个定期更新循环,在其中调用其所有子系统.
感谢您指出使用weak_ptr实际创建一个shared_ptr.期望shared_ptr在调用另一个非const函数期间不允许子系统或对象存储a .这样,任何函数都可以要求所有者从其集合中删除对象,并立即删除该对象.
我希望避免shared_ptr每次子系统调用时增加引用计数的开销lock(),因为它应该立即释放所有权(并确保在编译时就是这种情况.)
编辑2:更清楚地表达我的问题的示例代码
class Manager {
public:
Manager(); //Creates objects and stuff
void updateAllObjects() {
for (auto& o : mObjects)
o->update(*this);
}
void deleteObject(weak_ptr<WorldObject>); //May be called by other objects
vector<shared_ptr<WorldObject>> mObjects;
};
class WorldObject {
public:
virtual void update(Manager&)=0;
};
class Passenger : public WorldObject { …Run Code Online (Sandbox Code Playgroud) 我正在使用SDL2和C++制作基本游戏.我一直在慢慢改变我对原始指针的使用,以更安全的智能指针.
该_window变量是一个私有类成员:
private:
std::shared_ptr<SDL_Window> _window;
Run Code Online (Sandbox Code Playgroud)
以下代码有效:
_window = std::shared_ptr<SDL_Window>(SDL_CreateWindow(
"Game",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
SCREEN_WIDTH,
SCREEN_HEIGHT,
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
));
Run Code Online (Sandbox Code Playgroud)
以下代码不起作用:
_window = std::make_shared<SDL_Window>(SDL_CreateWindow(
"Game",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
SCREEN_WIDTH,
SCREEN_HEIGHT,
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
));
Run Code Online (Sandbox Code Playgroud)
抛出以下错误:
C:\...\include\type_traits(984): error C2027: use of undefined type 'SDL_Window'
Run Code Online (Sandbox Code Playgroud)
这非常令人困惑,因为它type_traits是标准库的一部分.因此,我不确定错误来源的位置,但在此处包含我的整个项目是不可行的.
什么可能导致抛出这样的错误,只需std::shared_ptr改为std::make_shared?
我有一个指向由new操作员初始化的类的指针。然后,我使用此指针设置一个std::unique_ptr。现在,据我所知,以下代码具有双重删除功能:一次是手动调用delete运算符,然后是唯一指针超出范围。该代码如何“正确”运行,即没有运行时异常?
#include <iostream>
#include <memory>
class A
{
public:
A()
{
std::cout<<"In A::A()\n";
}
~A()
{
std::cout<<"In A::~A()\n";
}
void printMyStr()
{
std::cout<<"In A::printMyStr()\n";
}
};
int main()
{
std::cout<<"hello world!\n";
A * pa = new A();
std::unique_ptr<A> upa(pa);
pa->printMyStr();
upa->printMyStr();
delete pa; // How does this not create problems?
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
hello world!
In A::A()
In A::printMyStr()
In A::printMyStr()
In A::~A()
In A::~A()
Run Code Online (Sandbox Code Playgroud)
显然,即使只创建了一个对象,析构函数也会运行两次。这怎么可能?
注意:我在64位linux上使用gcc 7.3.0。
我可能未正确输入标题,但在以下示例中更容易解释,然后有人可以编辑标题。
考虑以下代码片段:
#include <iostream>
#include <memory> // for std::unique_ptr
class Resource
{
public:
Resource() { std::cout << "Resource acquired\n"; }
~Resource() { std::cout << "Resource destroyed\n"; }
};
int main()
{
Resource* res = new Resource;
std::unique_ptr<Resource> res1(res); // Resource created here
delete res;
std::cout << "res1 is " << (static_cast<bool>(res1) ? "not null\n" : "null\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
打印:
$ ./a.out
Resource acquired
Resource destroyed
res1 is not null
Resource destroyed
Run Code Online (Sandbox Code Playgroud)
我们创建了动态分配的资源,然后创建了拥有此资源的唯一指针(res1)。唯一指针使我们不必担心必须手动删除资源。
但是,让我们假设像上面的代码一样,我们还是手动删除了资源(之后没有将其设置为null)。然后,当res1超出范围时,难道不是要删除已经被释放的东西吗?
c++ ×10
smart-pointers ×10
c++11 ×5
pointers ×3
unique-ptr ×2
memory-leaks ×1
qt ×1
qt-creator ×1
sdl ×1
shared-ptr ×1
templates ×1