Child Class reference parent class

I am trying to model a car object and I want the car object to have a child engine object but I want the engine object to have a pointer to the car object

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
class Car;

class Engine{
    private:
        Car carObject;
    public:
        Engine(Car * car){
            this->carObject = *car;
        }

};

class Car{
    private:
        Engine engine(this);
    public:
        Car(){

        }
};

int main(){
    Car car;
    return 0;
}


But I am getting a bunch of errors.
1
2
3
4
5
6
7
8
9
10
C:\cpp-playground\pointers\this_pointer.cpp:6:13: error: field 'carObject' has incomplete type 'Car'
         Car carObject;
             ^~~~~~~~~
C:\cpp-playground\pointers\this_pointer.cpp:2:7: note: forward declaration of 'class Car'
 class Car;
       ^~~
C:\cpp-playground\pointers\this_pointer.cpp:16:23: error: expected identifier before 'this'
         Engine engine(this);
                       ^~~~
C:\cpp-playground\pointers\this_pointer.cpp:16:23: error: expected ',' or '...' before 'this'

Anything wrong with my modelling?
Just to get the terminology right...

A child class inherits from a parent class. This models an is-a relationship.

In your code you're not using inheritance, which is correct because an engine is not a car, but that means you don't have any child or parent classes.

What you have is called "composition", one class containing an instance of another class, which models a has-a relationship. A car has an engine.


shaefayejem wrote:
I want the engine object to have a pointer to the car object

In that case you need to make carObject into a pointer
 
Car* carObject;
and not dereference the car pointer in the constructor.
 
this->carObject = car;

Another problem with your code is that you cannot specify default member initializers using normal parentheses. You have to use = or {}.
 
Engine engine{this};
Last edited on
Ohhh, got it. Thank you for the clear concept explanation about inheritance and composition.

Another problem with your code is that you cannot specify default member initializers using normal parentheses. You have to use = or {}.

I have an additional doubt though.. so I cannot use parenthesis but this works.
When you say you are referring to the "=" then it means dynamic allocation using "new"?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
class Car;

class Engine{
    private:
        Car * carObject;
    public:
        Engine(Car * car){
            this->carObject = car;
        }

};

class Car{
    private:
        Engine engine{this};
        //This does not work
        //Engine engine = new Engine(this); 
    public:
        Car(){

        }
};

int main(){
    Car car;
    return 0;
}


When I use this
Engine engine = new Engine(this)

I am getting below error, based on my understanding, I am passing the "this" car pointer to the Engine
1
2
error: could not convert '(operator new(8), (<statement>, ((Engine*)<anonymous>)))' from 'Engine*' to 'Engine'
         Engine engine = new Engine(this);

No, I meant like
 
Engine engine = this;

Although you might want to disable this syntax by marking the constructor as explicit.
1
2
3
explicit Engine(Car * car){
    this->carObject = car;
}
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c46-by-default-declare-single-argument-constructors-explicit

new returns a pointer so you need to use a pointer variable
 
Engine* engine = new Engine(this);
and then you need to use delete when you are finished using the object
 
delete engine;
otherwise you'll have a "memory leak" (using "smart pointers" like std::unique_ptr could help with this).
Last edited on
Thank you.. you are awesome.. learned a lot from this question of mine.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Car;

class Engine {
private:
	Car* carObject {};

public:
	explicit Engine(Car* car) : carObject { car } {}
};

class Car {
private:
	Engine engine { this };

public:
	Car() {}
};

int main() {
	Car car;
}


The question now though is - what about copy constructor and assignment?

That can of worms makes one ask: Why should engine know the car that it is in?

Remember, car has an engine. Car will use the engine. Car will use the interface of the engine. What information (about car) does the engine actually need? The car can surely supply that info without handing out this to engine.


PS. Boats and planes have engine too. Engines that must point to cars will not fit.
Last edited on
Your Car class as you originally wrote it (if you could construct it) would be infinitely recursive. i.e. C Car has a Engine. That engine has a Car. That Car has a Engine. Ad infinitum.

As keskiverto wrote: WHY do you want to do this? There is no reason that an Engine needs a pointer to it's Car class.
It could be used for reverse look-up. Given an Engine, what Car is it used in? You could have polymorphic classes based upon a base class of say Vehicle. Then Engine could hold a pointer to Vehicle.

However, as Car has Engine (or Vehicle has Engine) I agree about why should Engine have any knowledge about it's use? In practice you'd have say a vector of Car (as it's unlikely you'd have a program that only dealt with one Car!). If you needed to say interrogate which Car has a particular Engine (given say an Engine serial number) then this can be done otherwise.

If you have a circular reference (needing a class to be forward declared), then this often points to a design issue requiring in many cases a re-think.
Topic archived. No new replies allowed.