0
#include <iostream>

struct Class1 {
    Class1(int var1_);
    int var1;
};

Class1::Class1(int var1_)
    : var1(var1_)
{
    //how to get a referecnce to the instance of class2 ???
}

struct Class2 {
    Class1 instance1;
    Class2(int var);
};

Class2::Class2(int var)
    : instance1(Class1(var))
{
}

int main()
{
    Class2 instance2(3);
}

In the main function I create a instance of Class2. Class2 has a member from Class1, so the consructor of Class2 calls the constructor of Class1.

Inside the constructor of Class1 I would like to get a reference to the instance of Class1, i.e. the instance which created the instance of Class2. How can one achieve that without passing the address to the constructor? 'this' would refer to the just created Class2 instance and not to the Class1 instance which caused the creation of the Class2 instance. Any Input is appreciated! :)

Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52
Simon
  • 325
  • 1
  • 6
  • 1
    Please put four spaces at start of each C++ code line, and provide some [mre] - with a `main` function. Did you consider using [smart pointers](https://en.cppreference.com/w/cpp/memory) ? Are you allowed to use [container](https://en.cppreference.com/w/cpp/container)s ? If not, why? [edit](https://stackoverflow.com/posts/68283571/edit) your question to explain – Basile Starynkevitch Jul 07 '21 at 09:42
  • 1
    Other than passing the 'parent' address to the 'child' constructor, there's no obvious way to do this. See also: [Is there a Modern C++ way for a constructor to know its 'container' class?](https://stackoverflow.com/q/59308688/10871073). – Adrian Mole Jul 07 '21 at 09:42
  • Are you allowed to *generate* C++ code, perhaps with the help of [ANTLR](http://antlr.org)? or with [GPP](https://logological.org/gpp) ? – Basile Starynkevitch Jul 07 '21 at 09:47

1 Answers1

2

You cannot.

Only the pointer to the current object is implicitely passed in this. Any other element has to be explicitely passed. The constructor Class1::Class1(int var1_) cannot have a hidden reference to a Class 2 object, because it could have been created outside a Class2 context.

If you want to be able to use a reference to the Class2 object, you must pass it explicitely:

Class1::Class1(int var1_, Class2& parent);

and later:

Class2::Class2(int var): instance1(Class1(var, *this))

But beware: inside Class1 ctor, you can store the address of the Class2 object, but not use it because it is not yet fully constructed.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • Thanks four your answer! I thought the same way but in another forum someone told me the use of lambda expressions and capturing variables makes it possible to get such a hidden reference. But anyway, passing the address to the constructor is also fine even though it's blowing up the code a little bit. – Simon Jul 07 '21 at 10:09
  • @Simon: A lambda is only an anonymous function. That means that you could use a *factory* (be it a lambda a function or whatever) using the original ctor **and** the creator object, and that factory could *inject* the creator into the `Class1` object. But it cannot be available in `Class1` ctor unless it is an explicit parameter. – Serge Ballesta Jul 07 '21 at 10:13
  • @Simon - A lamba like you describe is essentially an anonymous data structure that would contain a captured pointer or reference to the instance of `Class2`. Since that lambda would need to be passed to the constructor of `Class1`, the technique is just passing the address of the `Class2` in a more complicated way. – Peter Jul 07 '21 at 10:15