0

Similar questions can be found: Can a c++ class include itself as an member? and Create an instance of a class in the class itself

They are elucidative, but the "memory" factor that almost everybody says its not clear to me. I agree with the "loop structure" in the compilation, but I don't see the memory usage.

struct A {
    A data_member;
};
int main(){ A object_1;}

In the code above data_member is a subobject of object_1. So data_member is nested in object_1 (source). If the data_member object were created in the same storage of object_1 than the lifetime of object_1 wouldn't end (source_2).

If we changed the A data_member for int hi , then sizeof(object_1) would be 4 and the pointer to the object_1 would point to the memory of int hi. Similarly it occurs the same when creating an char, long long int, bool data member, so I assume it must be the same for a A type.

My point is that when we are creating object_1 it creates infinitely objects, all of them in the exactly memory location. Where does come this use of memory ?

Edit 1: Since aparently all infinity objects would be created in the same memory location, somewhat "overriding".

  • 4
    I don't get the question. A class can't contain a non-static member of its type, otherwise you would need infinite storage to hold the class, and that is not possible. – NathanOliver Nov 16 '21 at 14:13
  • I don't see why would need infinity storage, so I writed my point of view, expecting that someone points where my argument is wrong –  Nov 16 '21 at 14:14
  • 2
    You understand that each subobject needs its own memory, right? For example you could say `object_1.data_member.data_member.data_member.....` ad infinitum where each of those subobjects could be mutated independently – Cory Kramer Nov 16 '21 at 14:15
  • 1
    @Roman Something like `struct A { A member; };` doesn't store a pointer to a `A`. It stores an entire `A` within itself. The size of a class is at least the sum of the size of its members, so in this case the size of `A` is at least the size `A`, it is self-referencing. C++ *could* have arbitrarily chosen a size of 0, but that generally isn't a very useful case. For `A` to be of use, it would almost certainly need another member. In that case, the size of `A` is at least the size of `A` plus some non-zero value. It is now recursively infinite. – François Andrieux Nov 16 '21 at 14:18
  • `struct A` has a `data_member` of type `A` which has a `data_member` of type `A` which has a `data_member` of type `A`... Memory concerns aside, a class cannot be used as a member before it isn't completely defined. That's how C++ is ruled, and how compilers are implemented. That rule includes that a `class` cannot contain itself as a member. (It can have a pointer to itself as member as pointers doesn't require a complete type for declaration.) Btw. I believe certain other languages support such recursive data types but C++ doesn't. – Scheff's Cat Nov 16 '21 at 14:20
  • @Roman `object_1` has an `A` member, that `A` member also has an `A` member, that `A` member also has an `A` member, that `A` member also has an `A` member, that `A` member also has an `A` member ... See how it you would have an object that has in infinite size now? – NathanOliver Nov 16 '21 at 14:21
  • 1
    Pointers to different objects of the same type can't compare equal. That means `&object_1.data_member` couldn't be equal to `&object_1.data_member.data_member`. You would therefore need to reserve infinite addresses every sub-object. – François Andrieux Nov 16 '21 at 14:25
  • @FrançoisAndrieux, For your first comment I understood that without any other member and not being of use, the size of `A` could be atleast of `A`, what "teorethically" could have finite size, despite the fact that "Pointers to different objects of the same type can't compare equal". Right? –  Nov 16 '21 at 14:29
  • @CoryKramer, I think that each subobject S needs a memory, but this memory could be the same memory of the "imediate object" that contains S. –  Nov 16 '21 at 14:34
  • 1
    @Roman It's hard to say. Objects can have the same address as their first member, but those will necessarily be different types because of the rule that objects can't contain themselves. If that restriction was removed, a lot of other rules would need caveats and exceptions to handle that case. So in theory it could be implemented, but it it would require a lot of effort to make it work. It isn't just a case that the standard doesn't bother with allowing something that should intuitively work. As-is it isn't compatible with other rules so it is forbidden. – François Andrieux Nov 16 '21 at 14:38
  • 1
    @Roman I think it would be hard to conceive of *any* programming language that both has self-consistent reference semantics *and* allow this. If you allow this design, then you necessarily need to forfeit the ability to compare references, pointers or any analogue to these concepts, which to me seems like a deal breaker. To support both you would need a pointer-like thing that can represent an infinite number of different possible states. So what I think it possible in theory is having an object contain an instance of itself, but I can't imagine a way of usefully resolving the consequences. – François Andrieux Nov 16 '21 at 14:47
  • 1
    The infinite memory meme is a visual aid. Yes, it would be possible for the language to say that there is no extra memory used in corner cases like this, but the underlying issue still remains: the data structure itself is infinite, and computers simply can't deal with infinite data. – Pete Becker Nov 16 '21 at 14:59

0 Answers0