c++ - 如何设计一个类,其中用户/调用者可以选择使用自定义类提供自定义行为

标签 c++

我遇到一个问题,我想要一个类,在这个类中它的行为可以被另一个类定制,例如,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。

最佳答案

您无法检测堆栈和堆分配之间的区别(标准甚至没有提到堆栈),但这不是这里的问题。

Foo 不应该删除不属于它的东西。如果它自己想要一个拷贝,那么它应该只制作一个拷贝:

template <class T = Bar>
class Foo
{
  T t_;
public:
  Foo() {}
  Foo(const T& t) : t_(t) {}
};

或者如果你需要它是一个指针:

template <class T = Bar>
class Foo
{
  T* t_;
public:
  Foo() : t_(new T()) {}
  Foo(const T& t) : t_(new T(t)) {}
};

你不能随便删除别人给你的东西,这与你是否知道它是堆栈分配还是堆分配无关。如果您的 Foo 消失并被 delete 但调用代码仍想使用它怎么办?或者,如果同一个对象被传递给您的两个 Foo 对象,并且它们都删除 它怎么办?

您可以选择复制或不删除它。

复制的另一种方法是标记您使用的是自己的还是其他人的:

template <class T = Bar>
class Foo
{
  T* t_;
  bool owned;
public:
  Foo() : t_(new T()), owned(true) {}
  Foo(T* t) : t_(t), owned(false) {}
  ~Foo() { if (owned) delete t_; }
};

如果您想知道,t 在我之前的解决方案中是由 const-ref 传递的,而不是按值传递的,因此没有过多的开销,尽管复制可能会产生开销。

关于c++ - 如何设计一个类,其中用户/调用者可以选择使用自定义类提供自定义行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2249716/

相关文章:

c++ - 编译错误 : undefined reference to‘__atomic_fetch_add_4’

c++ - 通过隐式类型转换模拟接口(interface)

c++ - openfoam: flex yyin.rdbuf(std::cin.rdbuf() 错误

C++ Builder 2009 - 无法聚焦禁用或不可见的窗口

c++套接字接收图像并显示而不保存

c++ - 通信器 MPI_COMM_WORLD MPI_ERR_RANK :invalid rank 上的 MPI_Send 发生错误

c++ - opencv源码用cuda编译生成多重定义链接错误

c++ - Linux vs Windows std::map 赋值构造函数(为什么会有这样的差异?)

c++ - MinGW : How to upgrade GCC/G++ to version 5 on Windows?

c++ - async_pipe 子进程上的 async_read 不提供任何数据