使用C++子类实例作为默认参数?

gct*_*gct 2 c++ parameters inheritance default

所以我有几个类定义:

class StatLogger {
public:
  StatLogger();
 ~StatLogger();

  bool open(<parameters>);

private:
  <minutiae>
};
Run Code Online (Sandbox Code Playgroud)

并且从它下降的子类实现一个空对象模式(未打开它是它自己的空对象)

class NullStatLogger : public StatLogger {
public:
   NullStatLogger() : StatLogger() {}
};
Run Code Online (Sandbox Code Playgroud)

然后我有第三个类,我想在其构造函数中采用可选的logger实例:

class ThirdClass {
public:
  ThirdClass(StatLogger& logger=NullStatLogger());
};
Run Code Online (Sandbox Code Playgroud)

我的问题是,当我按上述方式执行时,我得到:

错误:"StatLogger&"类型参数的默认参数类型为"NullStatLogger"

如果我在定义中放置一个显式的强制转换,我得到:

错误:没有用于调用'StatLogger :: StatLogger(NullStatLogger)的匹配函数

抱怨没有来自NullStatLogger的构造函数,即使它是子类.我在这里做错了什么,这在C++中是否允许?

Jer*_*fin 5

我想使用继承和多态,ThirdClass需要使用指针或StatLogger对象的引用,而不是实际的对象.同样,在这种情况下,你几乎肯定需要StatLogger::~StatLogger()虚拟化.

例如,修改如下,代码应该干净地编译:

class StatLogger {
public:
  StatLogger();
  virtual ~StatLogger();

//  bool open(<parameters>);

private:
//  <minutiae>
};

class NullStatLogger : public StatLogger {
public:
   NullStatLogger() : StatLogger() {}
};

class ThirdClass {
    StatLogger *log;
public:
  ThirdClass(StatLogger *logger=new NullStatLogger()) : log(logger) {}
};
Run Code Online (Sandbox Code Playgroud)

编辑:如果您更喜欢引用,代码看起来像这样:

class StatLogger {
public:
  StatLogger();
  virtual ~StatLogger();

//  bool open(<parameters>);

private:
//  <minutiae>
};

class NullStatLogger : public StatLogger {
public:
   NullStatLogger() : StatLogger() {}
};

class ThirdClass {
    StatLogger &log;
public:
  ThirdClass(StatLogger &logger=*new NullStatLogger()) : log(logger) {}
};
Run Code Online (Sandbox Code Playgroud)

  • @luke:这实际上是相当丑陋的,因为它写的是``ThirdClass`应该在它的dtor中删除`log`而且(丑陋的部分)只有当它使用一个被分配为默认参数的记录器时.否则,您*通常*希望镜像分配和删除,因此删除`log`应留给任何分配它的人... (2认同)