C++ calling a class constructor in a function argument

Started by
4 comments, last by Bregma 8 years, 5 months ago

So we have this:


//SecondClass
class SecondClass
{  
 private:
  int x;
  int y;
 public:
    SecondClass(int x, int y)
    {
      this->x = x;
      this->y = y;
    }
};

//MainClass
class MainClass
{
 private:
 SecondClass secondClass;
 public:
   MainClass(SecondClass &secondClass)
   {
      //stuff
   }
};
//main function




int main()

{

    MainClass mainClass(SecondClass secondClass(1,4));

}

I'm a little confused about the logic behind how can we call SecondClass' constructor as the argument. That is the moment when we create the object for the class? If yes, can i do this for other functions as well? I kinda answered my own question by asking this but i'm not sure..Can we call the constructor later in the code? For example i create my object now and later i call the constructor?

Advertisement

There will always be the default constructor called for member objects. You could do it by declaring your secondClass member as a (smart-) pointer and allocating it at a later point in time, but unless you have a good reason to do it, you should stay with a direct member. Also, your code in main is not quite right:


  MainClass mainClass(SecondClass(1,4));

The way to directly call the (copy-) constructor for your member is to use the initializer-list of the constructor:


public:
  MainClass(SecondClass &secondClass)
    : secondClass(secondClass) {
    // stuff
  }

There will always be the default constructor called for member objects. You could do it by declaring your secondClass member as a (smart-) pointer and allocating it at a later point in time, but unless you have a good reason to do it, you should stay with a direct member. Also, your code in main is not quite right:


  MainClass mainClass(SecondClass(1,4));

The way to directly call the (copy-) constructor for your member is to use the initializer-list of the constructor:


public:
  MainClass(SecondClass &secondClass)
    : secondClass(secondClass) {
    // stuff
  }

Is there a difference between using two variables to hold the values i need and doing this?

And the compiler knows that SecondClass has been declared inside the class, and thats why i'm not given an error with that? I'm confused...can you explain me the logic behind it?

'SecondClass' has not been declared inside the MainClass.

'secondClass' has been declared to be member data of type 'SecondClass' inside MainClass. Obviously when you say something contains something, you should be able to use it.

Are you saying the code was compiling that way? That sounds unlikely to me...

First of all you have a syntax error in your main function (the one I showed you). If SecondClass had a default constructor (which it doesn't have, because you declared a non-default constructor manually), then the constructor of MainClass would have implicitly called the default constructor of SecondClass (which would have left x and y uninitialized because they are not objects), then it would just have forgotten about the SecondClass reference you passed to the constructor and do nothing with it.

But as I said, I don't think you have ever compiled that code.

Can we call the constructor later in the code? For example i create my object now and later i call the constructor?

Just to be clear: a constructor is not a function in C++. It's a constructor.

You can not call a constructor (directly). You can construct an object, which will invoke a constructor as a part of the process. There are various types of constructors, some of which can be created by default if you do not supply your own or instruct the compiler not to do so on its own. It's important to learn the types of constructors and where and how they're used and when they're defaulted.


MainClass mainClass(SecondClass secondClass(1,4));

That's not valid syntax. You can construct a temporary SecondClass object and pass that as an argument like this.


MainClass mainClass(SecondClass(1,4));

Notice that that constructs an unnamed temporary SecondClass object, so your original code would still not compile because you can not take a reference of an unnamed temporary. You would need to declare your MainClass constructor like this.


  MainClass(SecondClass const& secondClass)
  : secondClass(secondClass)
  {
    // stuff
  }

The const there is very important, since you can take a const reference to an unnamed temporary.

What ends up happening there is the unnamed temporary you created as an argument gets copied (using SecondClass' copy constructor) into the secondClass member variable of the MainClass object. If you're lucky, the optimiser will elide the copy and construct the object directly in place (ie. skips the copy entirely), but the copy constructor still needs to be visible -- and the default copy constructor is visible.

Stephen M. Webb
Professional Free Software Developer

This topic is closed to new replies.

Advertisement