【发布时间】:2011-01-16 00:32:39
【问题描述】:
我遇到一个问题,我想要一个类,它的行为可以由另一个类自定义,例如,Foo 的构造函数接受某种类型的类的参数:
class Bar { //The default class that define behavior
};
template <typename T = Bar>
class Foo {
public:
Foo(T* t = 0) t_(t) {
if (t_ == 0) t_ = new T();
}
~Foo() {
delete t_;
}
}
现在如果有人在客户端代码中使用 Foo:
Foo foo;
一切都很好。但是,如果我们想提供自定义类:
class Bar1 { };
Foo<Bar1> foo(new Bar1()); // This is OK
Bar1 b;
Foo<Bar1> foo(&b); // Error, b is not dynamically allocated
我可以使用任何设计模式来防止这种错误吗?或者,是否有任何技术或语义可供 Foo 类的用户选择/指定谁拥有 bar 对象?所以例如上面的 Foo 析构函数可以是这样的:
~Foo() {
if (t_ is owned by this object) delete t_;
}
Bar 或 Bar1 或任何在 Foo(T* t) 中作为 t 传递的类可能是一个大对象,所以如果可能的话,我宁愿不按值传递它。
更新: 我的想法是让用户能够执行以下操作:
Foo foo(new Bar(1, 2, etc..));
//or this:
Bar bar(1, 2, etc..);
Foo foo(bar);
但是如果 bar 是一个大对象(例如,包含一个数组),那么按值传递 bar 将是低效的。唯一的方法是让 bar 通过引用或指针传递,但我也希望用户能够将 bar 与参数化构造函数一起使用,因此我的困惑开始了。 关于自动变量范围,如果用户执行以下操作将是安全的:
int main() {
Bar1 bar1(1,2,3);
Foo foo(&bar1);
return 0;
}
只要 Foo 不删除 bar1。
【问题讨论】:
-
啊。这是我最喜欢的咆哮。
-
自从我在 C++ 中工作已经有一段时间了,所以我可能是错的,但是如果 Bar1 在堆栈上分配并且比你的 Foo 实例更早超出范围,那么 Foo 将有对已被破坏的对象的引用。复制或使用智能指针的另一个原因如下面的答案所示。
-
@Martin:不,不一样,因为我不想覆盖 new 和 delete 运算符或类似的东西,也许标题有点误导。
-
@leiiv:还是一模一样。你想做的事情是 1) 不实用 2) 没用 3) 已经被问过一百万次了。
标签: c++