0

I have the following classes:

class ArithmeticExpression
{
public:
    ArithmeticExpression(std::string expr);
}


class Command
{
public:
    Command(){};
    //this is a virtual class
}

class CommandAssign : public Command
{
private:
    ArithmeticExpression expr;

public:
    CommandAssign();
    CommandAssign(ArithmeticExpression);
}

Now when I try to write the constructor for the CommandAssign class as in:

CommandAssign::CommandAssign(ArithmeticExpression expr)
    :Command()
{
    this -> expr = ArithmeticExpression(expr.getExpr());
}

I get the error:

no matching function for call to ‘ArithmeticExpression::ArithmeticExpression()’ :Command()

Apparently I can fix that by adding an empty constructor in ArithmeticExpression class that does not do anything. What is it so special about this empty constructor that makes it work? I do not explicitly call anywhere. Do you always need to define an empty constructor in C++?

I wanted to emphasize that although from the title it seems that my question is similar to the one some users suggested as being a duplicate of, the answer I was looking for is NOT there. I was simply trying to understand what happens when a constructor is called and how to avoid defining a useless default constructor, which I knew already is not automatically defined by the compiler in the case where I define one with parameters.

scapiskipi
  • 63
  • 7
  • 1
    see related: http://stackoverflow.com/questions/5498937/when-do-we-need-to-have-a-default-constructor – EdChum Apr 16 '14 at 12:26
  • When you add a constructor to a class, the default constructor is not generated automatically any more. – Neil Kirk Apr 16 '14 at 12:27
  • Your `Command` class embeds a private instance of `ArithmeticExpression` which is default-constructed in your current code, and `ArithmeticExpression` defines a non-default constructor, so yes, you need to add a default constructor to that class. – Frédéric Hamidi Apr 16 '14 at 12:27
  • You can initialize object in initializer list so default constructors wont be called – CucumisSativus Apr 16 '14 at 12:28
  • Is this real code? The constructor of `ArithmeticExpression` is `private` and `Command` is not a friend. It shouldn't be able to call it in the first place. – Benjamin Bannier Apr 16 '14 at 12:37
  • Can you give me an example of how I would initialize object in initializer list? – scapiskipi Apr 16 '14 at 12:39
  • It's not exactly the code... I just took the relevant parts from it, but I forgot to specify that the constructors are actually public. As I said, it compiles with the default constructor added. – scapiskipi Apr 16 '14 at 12:40
  • How do you expect a good answer if you don't show us something small we can compile and which shows the symptoms you are seeing? You might inadvertently have drop something important. Without a http://www.sscce.org/ this isn't very helpful. – Benjamin Bannier Apr 16 '14 at 12:44

2 Answers2

4

A default constructor will only be automatically generated by the compiler if no other constructors are defined.

EDIT:

The default constructor is needed for object initialization.

3

All members are initialised before the constructor body begins. If one doesn't have an entry in the initialiser list, then it will be default-initialised; but this is only possible (for a class type) if it has a default constructor.

expr is not initialised in the initialiser list, and doesn't have a default constructor (since declaring any constructor prevents one from being implicitly generated), so it can't be initialised - hence the error.

You should initialise it in the list, rather than reassigning it in the constructor body:

CommandAssign::CommandAssign(ArithmeticExpression expr) :
    expr(expr.getExpr())
{}

Note that there's no need to explicitly default-construct the Command sub-object. This also requires the constructor of ArithmeticExpression to be public: it's private in your example code.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644