[英]Using smart pointers as a class member
I have been reading up on smart pointers and recently in class my TA said that we should never use raw pointers. 我一直在学习智能指针,最近在课堂上我的助教说我们永远不要使用原始指针。 Now, I've done a lot of reading online and looked at different questions on this website but I'm still confused on some aspects of smart pointers. 现在,我已经做了大量的在线阅读,并在此网站上研究了不同的问题,但是我仍然对智能指针的某些方面感到困惑。 My question is: which smart pointer would I use if I want it to be used across my program? 我的问题是:如果要在程序中使用它,我将使用哪个智能指针? I'll show some code. 我将显示一些代码。
So I have a basic Application class that makes declarations of objects from class AI. 因此,我有一个基本的Application类,该类从AI类声明对象。 Note: I have two different smart pointers, a unique one and a shared one, for testing reasons. 注意:出于测试原因,我有两个不同的智能指针,一个是唯一的,一个是共享的。
// 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;
};
In the Application init function, I want to create the AI object, and then I want to use it in the update function. 在应用程序初始化函数中,我想创建AI对象,然后在更新函数中使用它。 I am not sure if I am declaring my pointer right at all, but I know for a fact that it compiles and it works for assigning and printing out data in the init function. 我不确定我是否完全正确地声明了指针,但是我知道它可以编译并且可以在init函数中分配和打印数据。 More code below. 下面有更多代码。
void Application::init()
{
//.. other initialization's.
std::shared_ptr<AI> temp(new AI());
sh_AI = &temp;
sh_AI->isGoingFirst = true;
//.. other initialization's.
// Function ends.
}
void Application::update()
{
if(sh_AI->get()->isGoingFirst == true)
{
// Do something
}
else
{
// Do something else
}
// Other code below
}
Later in my program, the update function is called, which uses the same AI smart pointer that I declared in my class Application. 在程序的稍后部分,将调用update函数,该函数使用与我在类Application中声明的AI智能指针相同的函数。 What I have found out is that the smart pointer AI object is being deleted. 我发现是智能指针AI对象正在被删除。 I understand that smart pointers have automatic memory management, but is there a smart pointer that will allow you to use a it in different functions without creating any major problems, such as memory leaks or dangling references? 我知道智能指针具有自动内存管理功能,但是有没有一个智能指针可以让您在不同的功能中使用它,而不会造成任何重大问题,例如内存泄漏或悬挂引用? Or am I missing the whole point of smart pointers? 还是我错过了智能指针的全部要点?
I'm sorry if this was answered in another question but I read into a lot of the other questions, and while I understand more about smart pointers, I'm still learning. 很抱歉,如果在另一个问题中回答了这个问题,但我阅读了许多其他问题,虽然我对智能指针有了更多的了解,但我仍在学习。 Thank you! 谢谢!
As Neil Kirk pointed out in the comments, these declarations are not what you want: 正如Neil Kirk在评论中指出的那样,这些声明不是您想要的:
unique_ptr<AI> *u_AI; // AI object using a unique pointer
shared_ptr<AI> *s_AI; // AI object using a shared pointer
u_AI and s_AI are still objects to raw pointers. u_AI和s_AI仍然是原始指针的对象。 The whole point is to remove the need to manage the raw pointer directly. 重点是消除直接管理原始指针的需要。 So now you replace them with: 所以现在您将它们替换为:
unique_ptr<AI> u_AI; // AI object using a unique pointer
shared_ptr<AI> s_AI; // AI object using a shared pointer
to assign your created pointer, you use the function make_unique or make_shared: 要分配创建的指针,请使用函数make_unique或make_shared:
u_AI = unique_ptr<AI>(new AI()); // Yu may be able to use make_unique like
// make_shared but it's new to C++14. may not be available
s_AI = make_shared<AI>();
Then, when you need to access them, you just pretend they are pointers, so in your update function: 然后,当您需要访问它们时,您只需假装它们是指针,因此在更新功能中:
if(sh_AI->get()->isGoingFirst == true)
becomes: 变成:
if(sh_AI->isGoingFirst == true)
As for when to use unique_ptr vs shared_ptr, you answer that by answering the following question: What do I want to happen when someone makes a copy of Application
? 至于何时使用unique_ptr与shared_ptr,您可以通过回答以下问题来回答:有人制作Application
副本时我要怎么办? ie: 即:
Application app1;
app1.init();
Application app2 = app1; // ?? what happens to AI object in app2?
There are 3 possible answers: 有3种可能的答案:
I don't want there ever to be a copy of Application. 我不想再有一份Application的副本。 (Which makes sense for a class called Application). (这对于称为Application的类来说是有意义的)。 In this case it doesn't really matter (in which case I would default to unique_ptr) and remove the copy constructor: 在这种情况下,这并不重要(在这种情况下,我将默认为unique_ptr)并删除复制构造函数:
Application(const Application&) = delete; Application(const Application&)=删除;
Short answer: Since your pointer is public, I suggest you use a shared_ptr
. 简短答案:由于您的指针是公共的,因此建议您使用shared_ptr
。 However, your pointer does not need to be public so if it was private you could use a unique_ptr
since you only use it in your own instance. 但是,您的指针不必是公共的,因此,如果它是私有的,则可以使用unique_ptr
因为您只能在自己的实例中使用它。
The truth is though that it does not really matter much (and I know I'll get some downvotes with this). 事实是,尽管这并没有多大关系(我知道我会对此表示不满)。 There are two reasons to use unique_ptr
: 使用unique_ptr
有两个原因:
On the other hand if you need to ever share the pointer (even in a read-only way) then you will have to use a shared_ptr
. 另一方面,如果您需要共享指针(即使是只读方式),则必须使用shared_ptr
。
A lot of times it is more convenient to use shared_ptr
to begin with but for reason 2) above it is worth using unique_ptr
. 很多时候开始使用shared_ptr
更为方便,但出于上述原因2),值得使用unique_ptr
。
Not a reason to use unique_ptr
: performance. 不是使用unique_ptr
的理由:性能。 All I say is make_shared
. 我只说了make_shared
。
This is how you define a smart pointer: 这是定义智能指针的方式:
std::shared_ptr<AI> s_AI;
std::unique_ptr<AI> u_AI;
This is how you initialize it: 这是您如何初始化它:
s_AI = std::make_shared<AI>(); // or
s_AI = std::shared_ptr<AI>(new AI);
u_AI = std::unique_ptr<AI>(new AI);
Note that there is no std::make_unique in C++11. 请注意,C ++ 11中没有std :: make_unique。 It's going to be in C++14 and it's not that hard to write a replacement but fact is that in C++11 there is none. 它将用C ++ 14编写,编写替代文件并不难,但事实是在C ++ 11中没有。
This is how you use the pointers: 这是使用指针的方式:
s_AI->isGoingFirst;
That's it, it behaves like a normal pointer. 就是这样,它的行为就像一个普通的指针。 Only if you have to pass it to a function that needs a pointer you need to use .get()
. 仅当您必须将其传递给需要指针的函数时,才需要使用.get()
。
here is how you delete (empty) the pointer: 这是删除(空)指针的方法:
s_AI.reset();
Again, I suggest you make your pointer private. 同样,我建议您将指针设为私有。 If you need to pass it out make sure you use a shared_ptr
and write a getter method: 如果需要将其传递出去,请确保使用shared_ptr
并编写一个getter方法:
std::shared_ptr<AI> getAI() const {
return s_AI;
}
Remember that if you do this you can't assume that your AI object will be destroyed when your Application object is. 请记住,如果执行此操作,则不能假定当您的Application对象被破坏时,您的AI对象将被破坏。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.