53

I´m trying to instantiate an object which has no default constructor so it can be referenced from any methods inside the class. I declared it in my header file, but the compiler says that the constructor for the class creating it must explicitly initialize the member, and I can´t figure out how to do that.

Really appreciate your answers, thank you in advance!

The snippet:

MyClass.h

include "MyOtherClass.h"

class myClass {

    private:
        MyOtherClass myObject;

    public:
        MyClass();
        ~MyClass();
        void myMethod();

}

MyClass.cpp

include "MyClass.h"

MyClass::MyClass() {

   MyOtherClass myObject (60);
   myObject.doSomething();

}

MyClass::myMethod() {

    myObject.doSomething();

}

MyOtherClass.h

class MyOtherClass {

   private:
      int aNumber;

   public:
      MyOtherClass (int someNumber);
      ~MyOtherClass();
      void doSomething();
}

MyOtherClass.cpp

include "MyOtherClass.h"

MyOtherClass::MyOtherClass (int someNumber) {
   aNumber = someNumber;
}

void MyOtherClass::doSomething () {
    std::cout << aNumber;
}
Tomaz Fernandes
  • 2,429
  • 2
  • 14
  • 18
  • 4
    You can create a pointer, and dynamically allocate it at the initialization site. – vukung Jul 18 '15 at 07:12
  • 2
    If you can do the initialization in the initialization list, that's your best option, see [this question](http://stackoverflow.com/questions/3704722/initializing-class-without-default-constructor). So it would be `MyClass::MyClass() : myObject(60) { }` – vukung Jul 18 '15 at 07:19
  • The initialization list worked, thank you very much!!! – Tomaz Fernandes Jul 18 '15 at 07:26
  • I don't understand this *an object which has no default constructor so it can be referenced from any methods inside the class*. Can you explain your logic here? AFAIK, any member can be referenced from any other member, regardless of its construction. – Walter Jul 18 '15 at 07:47
  • Possible duplicate of [Constructor for '' must explicitly initialize the reference member ''](http://stackoverflow.com/questions/19576458/constructor-for-must-explicitly-initialize-the-reference-member) – usr1234567 Feb 04 '16 at 07:44

4 Answers4

43

You are almost there. When you create an object in C++, by default it runs the default constructor on all of its objects. You can tell the language which constructor to use by this:

MyClass::MyClass() : myObject(60){

    myObject.doSomething();

}

That way it doesn't try to find the default constructor and calls which one you want.

TQA
  • 267
  • 3
  • 12
Russell Greene
  • 2,141
  • 17
  • 29
20

You need to initialize the myObject member in the constructor initialization list:

MyClass::MyClass() : myObject(60) {
   myObject.doSomething();
}

Before you enter the body of the constructor all member variables must be initialized. If you don't specify the member in the constructor initialization list the members will be default constructed. As MyOtherClass does not have a default constructor the compiler gives up.

Note that this line:

MyOtherClass myObject (60);

in your constructor is actually creating a local variable that is shadowing your myObject member variable. That is probably not what you intended. Some compilers allow you turn on warnings for that.

Chris Drew
  • 14,926
  • 3
  • 34
  • 54
4

There are two errors

  1. Your code MyOtherClass myObject(60); is not initializing the member of the class, but it's instead declaring a local variable named myObject that will hide the member inside the constructor. To initialize a member object that doesn't have a default constructor you should use member initialization lists instead.

  2. You are trying to learn C++ by experimenting with a compiler.

This second error is the most serious error and if not corrected is going to take you to a terribly painful path; the only way to learn C++ is by getting one or two good books and read them cover to cover. Experimenting with C++ doesn't work well.

No matter how smart you are there's no way you can guess correctly with C++, and in a sense being smart is even dangerous (because you may be tempted to skip over something "you understood already"): the reason is that it happens in quite a few places that the correct C++ way is illogical and consequence of historical evolution of the language.

In many places C++ is the way it is because of history and not because it makes sense, and no matter how smart you are there's no way you can deduce history... history must be studied.

6502
  • 112,025
  • 15
  • 165
  • 265
  • I am genuinely curious about the downvotes, any comment on why this is a bad answer would be helpful. – 6502 Jun 15 '21 at 06:37
  • 3
    I did not downvote your answer, but I would suspect that some people read it in the sentiment of "Go read a book". While that is not entirely wrong, I see how someone could feel rejected. Anyhow, the part about C++ being illogical in large parts, which makes dull study of specification details a necessity when learning the language, is sadly true. – SuperTasche Jun 20 '21 at 11:46
  • @SuperTasche: I think that if you make the mistake the OP made it means you're just experimenting with C++ and you never read about C++ syntax for constructors (may be coming from other languages). This is in my opinion a suicidal approach to C++ (been there done that) and going to read a good book is the best suggestion I can give. – 6502 Jan 25 '23 at 08:53
-1
MyClass::MyClass(): myObject (60){

   myObject.doSomething();

}

Initialization of the data member ends before constructor function body.in the function body you just assign

kiviak
  • 1,083
  • 9
  • 10