-1

Okay, first off this is a trivial question, but nonetheless it's bugging me. Disclaimer: I'm not a compiler engineer. But it seems to me the compiler in this case is requiring a constructor that is really not necessary. Code below; why is the B constructor that takes no parameters and does nothing being called when an already instantiated object of it's class is being passed to the constructor of another class? For reference I'm using g++ (GCC) 5.3.0 and have not tried it with any other compilers (and yeah I know GCC is not without its quirks):

#include <iostream>

namespace I_DO_NOT_GET_IT
{
    class A;
    class B;
}

class B
{
public:
    B()
    {
        std::cout << "\nWhy am I here?\n\n";
    }

    B(const int aInt, const char * aChar)
    {
        mInt  = aInt;
        mChar = aChar;
    }

    void identify()
    {
        std::cout << "\nI am an object of class B, owned by class A\n"
                  << "my integer data is "
                  << mInt
                  << " and my character data is \""
                  << mChar
                  << "\"\n\n";
    }

    int          mInt;
    const char * mChar;
};

class A
{
public:
    A(B an_instantiated_object_of_class_B)
    {
        b = an_instantiated_object_of_class_B;
    }

    // class A owns an object of class B
    B b;
};

int main()
{
    // create an object of class B
    B b(1, "text");

    // pass the B object to A, which uses it to instantiate its B object 
    // in the A constructor. 
    A a = B(b);

    // Have A's B object describe itself
    a.b.identify();

    return 0;
}
vishnu
  • 11
  • 2

1 Answers1

3
A(B an_instantiated_object_of_class_B)
{
    b = an_instantiated_object_of_class_B;
}

The default constructor of B is used when A::b is created before the constructors body runs, where an assignment b = ... occurs.

Use the initialization list instead:

A(B an_instantiated_object_of_class_B)
: b{ an_instantiated_object_of_class_B }
{
}

btw, your namespace I_DO_NOT_GET_IT is pointless. The declarations in there have nothing to do with your classes A and B.

Swordfish
  • 12,971
  • 3
  • 21
  • 43
  • I suppose I should have mentioned I do know to use the initialization list but in my code I need to instantiate as many as 416 objects of class B in class A, and it just seems worlds easier to do it by passing in already instantiated objects to the A constructor... – vishnu Oct 12 '18 at 05:23
  • 1
    @vishnu "in my code I need to instantiate as many as 416 objects of class B in class A" then you should have shown a code sample that is closer to your real code. Maybe add it to your question. – Swordfish Oct 12 '18 at 05:27
  • I used the namespace declaration just to highlight the point of my question, but yes it was useless. I simply do not understand why, in otherwise valid code, a constructor that takes no parameters is required when an object of that class that requires no parameters is never initiated. Especially when C++ writes such constructors in the case where programmers do not. But then again I'm neither a compiler engineer nor a C++ standards whiz... – vishnu Oct 12 '18 at 05:38
  • 1
    @vishnu "I simply do not understand why, in otherwise valid code, a constructor that takes no parameters is required when an object of that class that requires no parameters is never initiated." Again: The code in your question needs the default constructor because members are initialized/constructed \*before\* entering the constructors body. Show your \*real\* code if you want help/explanations. – Swordfish Oct 12 '18 at 05:43
  • So okay, it has to be there because C++ requires it, problem solved, thanks! – vishnu Oct 12 '18 at 05:47
  • @vishnu So it seems you don't want no input on your "in my code I need to instantiate as many as 416 objects of class B" problem. – Swordfish Oct 12 '18 at 05:51
  • @vishnu: "*I simply do not understand why, in otherwise valid code, a constructor that takes no parameters is required when an object of that class that requires no parameters is never initiated.*" Because subobjects of a class are always initialized *before* the code in a constructor begins. The *entire purpose* of member initializers is to declare how subobjects are initialized. It's no different from being confused why `B b; b = some_object;` will default-initialize `b` before assigning to it. It does that because that's what you said to do. – Nicol Bolas Oct 12 '18 at 06:00