Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a C++ child class instance as a default parameter?

So I have a couple classes defined thusly:

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

  bool open(<parameters>);

private:
  <minutiae>
};

And a child class that descends from it to implement a null object pattern (unopened it's its own null object)

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

Then I have a third class that I want to take an optional logger instance in its constructor:

class ThirdClass {
public:
  ThirdClass(StatLogger& logger=NullStatLogger());
};

My problem is when I do it as above, I get:

error: default argument for parameter of type ‘StatLogger&’ has type ‘NullStatLogger’

And if I put an explicit cast in the definition, I get:

error: no matching function for call to ‘StatLogger::StatLogger(NullStatLogger)

Complaining about not having a constructor from a NullStatLogger even though it's a child class. What am I doing wrong here, is this allowed in C++?

like image 427
gct Avatar asked Jan 31 '26 00:01

gct


1 Answers

I you want to use inheritance and polymorphism, ThirdClass needs to use either a pointer or a reference to StatLogger object, not with an actual object. Likewise, under the circumstances you almost certainly need to make StatLogger::~StatLogger() virtual.

For example, modified as follows, the code should compile cleanly:

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) {}
};

Edit: If you prefer a reference, the code looks something like this:

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) {}
};
like image 113
Jerry Coffin Avatar answered Feb 02 '26 14:02

Jerry Coffin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!