【发布时间】:2015-02-01 15:35:18
【问题描述】:
我在 C++ 中有一个旧的工厂实现,我想在其中使用唯一指针而不是原始指针。我的代码的一个最小示例如下。我有一个基类A 和一个派生类B。在main()中,我将1传递给A中的create方法,现在b1的类型变成了B。
#include <iostream>
#include <map>
class A {
public:
A() {}
virtual void Foo() {}
std::map<int, A *> ®isterType() {
static std::map<int, A *> map_instance;
return map_instance;
}
A *create(int n) { return registerType()[n]; }
};
class B : A {
public:
B() { registerType()[1] = this; }
void Foo() { std::cout << "I am B!\n"; }
};
static B b0;
int main() {
A *b1 = new A();
b1 = b1->create(1);
b1->Foo();
return 0;
}
现在如果我想将原始指针更改为唯一指针,我自然会得到一个错误集合(以下代码导致错误):
#include <iostream>
#include <map>
#include <memory>
class A {
public:
A() {}
virtual void Foo() {}
std::map<int, std::unique_ptr<A>> ®isterType() {
static std::map<int, std::unique_ptr<A>> map_instance;
return map_instance;
}
std::unique_ptr<A> create(int n) { return registerType()[n]; }
};
class B : A {
public:
B() { registerType()[1](this); }
void Foo() { std::cout << "I am B too!\n"; }
};
static B b0;
int main() {
std::unique_ptr<A> b1(new A());
b1 = b1->create(1);
b1->Foo();
return 0;
}
错误是:
In member function 'std::unique_ptr<A> A::create(int)':
use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = A; _Dp = std::default_delete<A>]'
std::unique_ptr<A> create(int n) { return registerType()[n]; }
In constructor 'B::B()':
no match for call to '(std::map<int, std::unique_ptr<A> >::mapped_type {aka std::unique_ptr<A>}) (B* const)'
B() { registerType()[1](this); }
^
所以我想知道:
- 是否打算在像我这样的情况下使用唯一指针? (我认为答案应该是肯定的!)
- 我需要将
this作为unique_ptr类型传递给registerType方法。如何将指向当前实例的指针(this关键字)的所有权传递给unique_ptr? (如果可能或打算可能的话。) - 如果在这里使用唯一指针是一个好习惯,我应该如何实现它?
【问题讨论】:
-
“我自然会收到一堆错误” - 请在您的帖子中包含错误的全文。随意省略出现在多行中的重复项。
-
我不明白这将如何与
std::unique_ptr一起工作。您当然可以将它们存储在std::map中,并且可以引用它们。但它们充其量只能被感动;没有复制。将它们从您的地图中移出是可行的,但是为什么要首先麻烦地拥有一张地图。看起来std::shared_ptr会为您的尝试带来更好的回报。(如果配置正确,您还可以设置共享this。) -
@a.sam 它以一种非常令人困惑的方式编写,您有一个“创建”函数,它不会创建任何东西,并且通过执行
b1 = b1->create(1);会泄漏内存 -
@PeterT:+1 表示您的精彩观点。因此,即使我在
A和B中添加析构函数,也无法避免内存泄漏。我对吗?那么,我怎样才能首先避免内存泄漏呢? -
@a.sam 如果你
new某事delete它。对于您的具体情况,首先不要创建A。将registerType和create设为静态,因为它们所做的只是访问静态数据成员并使用A *b1 = A::create(1);调用它
标签: c++ this factory smart-pointers unique-ptr