1

I'm fairly new to c++ with most of my writing having been in Python.

In Python, if I wanted to create a class to hold information about a Human, I could write a class which could hold its 'parent' as one of its variables. In Python, I'd do it roughly like this:

class Human:

    def __init__(self, name):
        self.name = name


first = Human("first")
second = Human("second")

second.parent = first

where second.parent = first is saying that the parent of the Human second is the Human first.

In c++ I tried to implement something similar:

class Human {

    public:
        Human parent;

};

int main() {
    Human first = Human();
    Human second = Human();

    second.parent = first;
}

This example comes with an error that field has incomplete type: Human. I get this, because it's saying that I can't have a Human in my Human object because there isn't yet a full definition of what a Human is. When I search for related posts, I keep coming up against solutions using forward declaration and pointers but I haven't been able to make it work properly.

I'd really appreciate any help in making the c++ example behave how I want it to.

Thanks.

evanr70
  • 139
  • 10
  • 1
    You should use a reference or a pointer for `parent` – πάντα ῥεῖ Sep 04 '18 at 10:54
  • 2
    First: You can't. Second: It makes no sense in your use case. So use a pointer or reference instead as πάντα ῥεῖ said. You don't want have a full copy of the parent class in your child one! – Klaus Sep 04 '18 at 10:56
  • what you want do declare is like a infinite [matroschka](https://en.wikipedia.org/wiki/Matryoshka_doll). The difficulty is probably to realize that in C++ values are values not references – 463035818_is_not_an_ai Sep 04 '18 at 11:08

4 Answers4

4

For example by using pointers:

struct Human
{
    Human* parent;  // The symbol Human is declared, it's okay to use pointers to incomplete structures
};

int main()
{
    Human first = Human();
    Human second = Human();

    second.parent = &first;  // The & operator is the address-of operator, &first returns a pointer to first
}

You can use references as well but those could be a little harder to work with and initialize.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • problem solved! I think that I had let pointers and addresses get scrambled up in my brain but this helped me sort it all out – evanr70 Sep 04 '18 at 11:13
  • while a pointer (and a reference) are proper and intuitive choices it is worth mentioning other choices, such as: `std::unique_ptr`, `std::shared_ptr` and `std::weak_ptr`, see also: https://stackoverflow.com/questions/63365537/c-instance-of-same-class/63365597#63365597 – Amir Kirsh Aug 12 '20 at 09:23
0

What you can do is

class Human {

public:
    Human * parent = nullptr;

};

It should be a pointer, & better initialized.

Amit G.
  • 2,546
  • 2
  • 22
  • 30
  • 1
    The actual issue is that to declare a member of `Human`, the compiler needs to know how much space is needed. But for that, it needs to know how much space is in a `Human`, _ad infinitum_ – Tas Sep 04 '18 at 11:21
0

Pointers make sense here, Pointers hold the memory address to whatever you are referencing without storing the actual data within that class.

E.G

class Human {

public:
    Human * parent;

};

Your parent is now actually stored as a memory address but with *parent it is being used an object, e.g you could do: myHuman.parent->parent (-> meaning de-reference and then ".")

Prodigle
  • 1,757
  • 12
  • 23
-1

You can do it by keeping a pointer property in the class of the same type. Like

class Human {
...
...
public : Human* parent;
...
...
}

And can be used as:

int main()
{
    Human* h1 = new Human;
    Human* h2 = new Human;

    h2->parent = h1;
    ...
    ...
    delete h1;
    delete h2;
}
Rizwan
  • 3,324
  • 3
  • 17
  • 38