我正在尝试更改我当前的设计,并希望使用智能指针(最好是unique_ptr
,因为 Herb Sutter 说,如果有疑问,默认情况下更喜欢unique_ptr
但是我很困惑,这适合我当前的设计,其中一个指针将被传递给多个类。
示例代码如下
class X {
private:
ZHandler* _mZHandler; //change it as unique_ptr or shared_ptr??
public:
X()
{
Z* zPtr = createUsingFactory(); // instantiated by legacy code factory function, createUsingFactory() is just representational
_mZHandler = new ZHandler(zPtr);
}
~X()
{
delete _mZHandler;
}
void callYfunc()
{
_mZHandler->funcY();
}
};
//ZHandler wraps the calls to Z as well as serves as event listner to Z
class ZHandler : public Z::ZEventListner {
private:
Z* _mPtrZ;
public:
ZHandler(Z* ptr) : _mPtrZ(ptr){}
void funcY()
{
_mPtrZ->funcZ();
}
void funcNotifyEvent
{
}
};
class Z {
private:
ZEventListner* _mZEventListner;
public:
class ZEventListner{
vitual void funcNotifyEvent() = 0;
};
void setEventListner(ZEventListner* ptr)
{
_mZEventListner = ptr;
}
ZEventListner* getEventListner(){return _mZEventListner};
void funcZ(){}
void funcNotify() //called by some other class
{
_mZEventListner->funcNotifyEvent();
}
};
问题是,unique_ptr
中的shared_ptr
指针是使用ZHandler
还是class X
? (因此函数和指针会在其他类中改变),
如果我使用unique_ptr
,那么我必须在ZHandler
函数中移动setEventListner
的ptr,一旦我这样做,原始指针将会丢失并进一步调用ZHandler
<{1}}是不可能的。
答案 0 :(得分:2)
智能指针完全是关于 所有权 。这意味着哪些对象负责删除其成员。因此,您应该查看哪些对象删除他们指向的内容。
如果设计不可能知道哪个指针将是最后一个引用对象(因此是用于删除它的那个),那么你应该使用<html lang="en">
<head>
<meta charset="UTF-8">
<title>Sample Site</title>
<link rel="stylesheet"href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css"/>
</head>
<body id="clrblk">
<div class="container">
<div id="loginbox" style="margin-top:50px;" class="mainbox col-md-6 col-md-offset-3 col-sm-8 col-sm-offset-2">
<div class="panel panel-info" >
<div class="panel-heading">
<div class="panel-title">Sign In</div>
<!--<div style="float:right; font-size: 80%; position: relative; top:-10px"><a href="#">Forgot password?</a></div>-->
</div>
<div style="padding-top:30px" class="panel-body" >
<% if (message.length > 0) { %>
<div class="alert alert-danger col-sm-12"><%= message %></div>
<% } %>
<form id="loginform" class="form-horizontal" role="form" method="post" action="/login">
<div style="margin-bottom: 25px" class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
<input id="login-username" type="text" class="form-control" name="user_name" value="" placeholder="username">
</div>
<div style="margin-bottom: 25px" class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
<input id="login-password" type="password" class="form-control" name="password" placeholder="password">
</div>
<div class="input-group">
<!--<div class="checkbox">
<label>
<input id="login-remember" type="checkbox" name="remember" value="1"> Remember me
</label>
</div>-->
</div>
<div style="margin-top:10px" class="form-group">
<!-- Button -->
<div class="col-sm-12 controls">
<button id="btn-login" type="submit" class="btn btn-success">Login </button>
</div>
</div>
<div class="form-group">
<div class="col-md-12 control">
<div style="border-top: 1px solid#888; padding-top:15px; font-size:85%" >
Don't have an account!
<a href="/signup">
Sign Up Here
</a>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</body>
</html>
。
另一方面,如果只有一个指针将超过所有其他引用,并且总是需要删除对象,那么它应该是{{ 1}}。
大多数 拥有 指针(需要删除内容的指针)往往是std::shared_ptr
。
如果你有一个对象的指针,总是比指针更长,并被其他一些对象删除,那么你应该使用 原始指针 < / strong>或最好 参考 。
因此,您必须确定设计中哪些对象生存最长,哪些对象将负责销毁他们指向的对象并相应地选择指针。
共享指针:当您不知道哪个指针必须删除该对象时,因为您不知道哪个指针最后会超出范围(或被删除)。
唯一指针:当指针对象需要删除之前,指向的对象将从一个地方被销毁,而该对象的所有其他裁判都将过期。
原始指针/参考:当其他人负责删除该对象时,因为此指针/引用需要访问该对象将在此之前过期。
答案 1 :(得分:1)
这不是问题的直接答案,而是避免与智能指针混淆的方法。首先,不要使用unique_ptr或shared_ptr。而是花一天时间了解RAII并尝试实施自己的&#34; unique_ptr&#34; (你可以看一下stl代码)。这将让您了解unique_ptr的工作原理。然后尝试实现自己的&#34; shared_ptr&#34;。实现自己的共享ptr的最简单方法是使用内部引用计数的对象。
在您了解它们如何工作之后,使用unique_ptr或shared_ptr会失去它的魔力,您应该知道何时使用它。