1

I have two classes, class A and Class B. I don't want either of them to have a default constructor, because both of them need to be instantiated with parameters. However, I can not seem to create an object of class A, inside of class B without using a default public constructor that would allow the classes to be instantiated without user defined values (Trying to avoid default values).

This is my setup:

Class of object I am trying to initialize inside of other class B:

ClassA.h

Class A  //No default constructor
{
public:
    A(int var1, int var2);    //Class A's Constructor
}

I want to create an instance of this object that is instantiated when Class B is instantiated, because I need the values passed into class B to instantiate Class A.

ClassB.h

Class B   //No default Constructor
{
public:
    A myClassA;    //The public variable in class B I want to hold an object of class A

    int somePublicVar;

    B(int var1, int var2, int var3);    //Class B's Constructor

}

I can't seem to get the myClassA object of type A to instantiate.

ClassB.cpp

B::B(int var1, int var2, int var3)
{
    B = A(var1, var2);
    somePublicVar = var3
}

I am new to C++ but I am very familiar with C# and C. But I can not seem to find the right syntax / process to complete this.

The more I have read the questions related to this problem, the more it seems that using pointers to achieve this is the "beginners" way to solve this problem since the object will need to manually be destroyed, so I am trying to do this without pointers. Is it possible? What is the best practice for this process?

I will resort to pointers if I must to achieve this, but I am struggling with that operation too, since if I define A as a pointer instead of an object, I get an error when I do this:

myClassA = &A(var1, var2);

I get:

"nonstandard extension used: class rvalue used as lvalue"

because my understanding is that A(var1, var2) scope is the constructor and will be deleted after the constructor completes, so we can't save a pointer to it. So I am not sure how I would utilize the pointer approach in this case either.

I can only seem to find partial answers to this question, but none of which seems to satisfy all conditions. I appreciate the help.

Edit 9/14/17:

I forgot to mention that I am also trying to have myClassA as a public variable inside of class B. If I don't have a default constructor, how can I prevent this from giving me the "No Default Constructor" error?

Mikev
  • 2,012
  • 1
  • 15
  • 27
WhatIsASyntax
  • 39
  • 1
  • 5

2 Answers2

7
B::B(int var1, int var2, int var3) : myClassA(var1, var2)
{}
AlexD
  • 32,156
  • 3
  • 71
  • 65
  • Thank you. I appreacite such a quick reply. But how can I define myClassA as a public variable inside of class B? It keeps giving me the default constructor error. – WhatIsASyntax Sep 14 '17 at 19:34
  • @WhatIsASyntax It should not make an error. Check all places that may try to call `A`'s default constructor. Here's a live example, it shows no compiler error in the output: http://coliru.stacked-crooked.com/a/d94463408244b094 – Guillaume Racicot Sep 14 '17 at 19:38
  • @WhatIsASyntax If you want a pointer to `A` as a member of `B`, you could do something like this: `class B { unique_ptr p; B::B(int var1, int var2, int var3) {p = make_unique(var1, var2);}`. – AlexD Sep 14 '17 at 19:39
  • @Guillaume Racicot & AlexD thank you both. This is a huge help! – WhatIsASyntax Sep 14 '17 at 19:43
  • @AlexD Thanks for the update about the pointer. That syntax is still a little foreign to me being that I'm new to C++, but I will break it down and try to understand it. Thanks again! – WhatIsASyntax Sep 14 '17 at 19:45
  • @WhatIsASyntax You could use `new` instead, but then (contrary to C#) you have to delete explicitly, On the other hand, having `A` (not a _pointer_ to `A`) as a member of `B` might be perfectly OK too. – AlexD Sep 14 '17 at 19:48
  • @AlexD Ah, yes, that makes sense. I have been reading that I should avoid "new" inside of C++ for that exact reason. So I am trying to learn the proper way to move things right out of the gate. I tried your original solution above and it works perfectly. I had totally forgot about using ":" after the constructors, as I have used that before in C# when dealing with overloaded constructor calls to the previous constructor. But I had no idea that would solve the issue of public declaration inside of class B. Thanks again! – WhatIsASyntax Sep 14 '17 at 20:11
1

Alex's explanation above is of course correct, but here's a link for you too: http://en.cppreference.com/w/cpp/language/initializer_list

Basically, if it's "after the : but before the constructor body" it is "constructed" with those arguments. Default constructor is never called. And since you only defined a non-default constructor, your class A doesn't have a no-argument constructor.

Kevin Anderson
  • 6,850
  • 4
  • 32
  • 54
  • Thank you so much. This makes a lot more sense! I didn't understand how AlexD's answer got around the public variable declaration but this explains everything. Thank you. – WhatIsASyntax Sep 14 '17 at 19:41