我有一个案例,我不确定是否应该使用unique_ptr
或按值传递Object。
假设我有一个类A,它有一个B类向量,C类也有一个B类向量。每次我在C类中向Vector添加B对象时,都应该从C类向量中删除,反之亦然。当对象C被销毁时,B Vector类中的所有对象都应该添加到A类
中的B向量中class B {
public:
B();
virtual ~B();
};
class A {
C & c;
std::vector<B> bs;
public:
A(C & c ): c(c){};
virtual ~A();
void add(B b){
bs.push_back(b);
c.remove(b);
}
void remove(B b){
bs.erase(std::remove(bs.begin(), bs.end(), b), bs.end());
}
};
class C {
public:
A & a;
std::vector<B> bs;
C(A & a): a(a) {
};
virtual ~C(){
for (B b : bs) {
a.add(b);
remove(b);
}
}
void add(B b){
bs.push_back(b);
a.remove(b);
}
void remove(B b){
bs.erase(std::remove(bs.begin(), bs.end(), b), bs.end());
}
};
我的问题:
shared_ptr
或unique_ptr
? B对象永远不会被两个对象拥有,而且它总是有一个所有者,所以我猜unique_ptr
更好,但我不确定。答案 0 :(得分:1)
如果复制构造B
代价高昂,那么(智能)指针可能是一个好主意(重新设计应用程序逻辑可能是另一种解决方案),
如果我理解正确,给定的B
实例始终由单个所有者操纵(A
或C
)。 std::unique_ptr
因此是合理的选择,
尝试以下实施方案。我没有编译它,但我认为你会得到一般的想法:)
class B {
public:
B();
virtual ~B();
};
class A {
C & c;
std::vector<std::unique_ptr<B>> bs;
public:
A(C & c ): c(c){};
virtual ~A();
// http://herbsutter.com/2013/06/05/gotw-91-solution-smart-pointer-parameters/
// (c) Passing unique_ptr by value means "sink."
void add(std::unique_ptr<B> b){
c.remove(b); // release the poiner from the other container
bs.emplace_back(b.get()); // emplace the pointer in the new one
b.release(); // emplacement successful. release the pointer
}
// http://herbsutter.com/2013/06/05/gotw-91-solution-smart-pointer-parameters/
// (d) Passing unique_ptr by reference is for in/out unique_ptr parameters.
void remove(std::unique_ptr<B>& b){
// @todo check that ther returned pointer is != bs.end()
std::find(bs.begin(), bs.end(), b)->release(); // first release the pointer
bs.erase(std::remove(bs.begin(), bs.end(), b), bs.end()); // then destroy its owner
}
};
class C {
public:
A & a;
std::vector<std::unique_ptr<B>> bs;
C(A & a): a(a) {
};
virtual ~C(){
for (auto&& b : bs) {
a.add(b);
// a is going to call this->remove()...
// unless calling this->remove() from "a"
// while this is being destroyed is Undefined Behavior (tm)
// I'm not sure :)
}
}
// http://herbsutter.com/2013/06/05/gotw-91-solution-smart-pointer-parameters/
// (c) Passing unique_ptr by value means "sink."
void add(std::unique_ptr<B> b){
c.remove(b); // release the poiner from the other container
bs.emplace_back(b.get()); // emplace the pointer in the new one
b.release(); // emplacement successful. release the pointer
}
// http://herbsutter.com/2013/06/05/gotw-91-solution-smart-pointer-parameters/
// (d) Passing unique_ptr by reference is for in/out unique_ptr parameters.
void remove(std::unique_ptr<B>& b){
// @todo check that ther returned pointer is != bs.end()
std::find(bs.begin(), bs.end(), b)->release(); // first release the pointer
bs.erase(std::remove(bs.begin(), bs.end(), b), bs.end()); // then destroy its owner
}
};
答案 1 :(得分:1)
如果必须,我只会使用public function User($arg) {
switch($arg) {
case "online":
return self::CheckKey(); // < -- At the start of this line.
break;
}
}
。您可能希望unique_ptr
仅限移动类型(例如B
)来限制所有权。
如果unique_ptr
移动费用昂贵,或者阻止复制B
是不切实际的,请使用B
,但要注意您正在为动态内存分配付费。< / p>
以下是在受代码启发的示例中,如何使用仅限移动unique_ptr
。如果您使用B
,则它应该完全相同:
unique_ptr