3 ms·
What has always bugged me about C++, but maybe I am overlooking some reason why this generally cannot work, is that it does not resolve circular dependencies su
by hacker42 10y ago
What has always bugged me about C++, but maybe I am overlooking some reason why this generally cannot work, is that it does not resolve circular dependencies such as this one:
// file: A.h
class A {
B* _b;
};
// file: B.h
class B {
A* _a;
};
I mean a pointer has a fixed size, so couldn't the compiler just leave some sort of type placeholder in class A until class B is eventually defined.
- jontro 10y agoThis can be done, check the end of this answer: http://stackoverflow.com/a/628079/429972 http://stackoverflow.com/a/628079/429972 // file: A.h class B; class A { B* _b; // or any of the other variants. };
- gruez 10y agoYou can also do this class A { class B* _b; };
- MaulingMonkey 10y agoStructure layout isn't the hard part, it's having the rest of the language cope with the ambiguity of everything. // Things.h namespace Foo { class A { C* c; }; } namespace Bar { class B { C* c; }; } Are A::c and B::c the same type? // TU1.cpp class C {}; Were you right? // TU2.cpp namespace Foo { class C {}; } namespace Bar { class C {}; } What about now? // TU3.cpp class C {}; namespace Foo { class C {}; } namespace Bar { class C {}; } This may get you shot, but is legal. What about now? Ahh - all three are in the same program. Just pretend they #included <c.h>, <foo/c.h>, and <bar/c.h>. Having A::c's type be different in different contexts is a violation of the "One Definition Rule", for which the punishment is undefined behavior. Although you can still recreate the above scenarios by just #including <Things.h> after <c.h> and company, but you're a bit more likely to have Things.h #include what it needs to clarify the situation. Hopefully. So maybe we can get away with it! void foo() { D * d; } Is that a pointer definition or invoking operator* against two globals? void bar() { E < 42 > e; } Now you're just fucking with me. Is that some comparison operators or a template? void baz() { F < (42) > f; } That didn't clarify anything. Stop it. void he_comes() { G < (42) > g(); } What do you mean I just declared a function? Stop it! v̹̊̈́̇ͦ̌ͭ͂ͅo̅̉̀ͪ̚ī̵̠̘̋d̸͚̪̝̹͙͆͛̿ ͉̜̳ͪͬ́ͣ̌ẑ̸̹̹̩̩a̡̰ͣͭ̄͒ͫ̇̚l̛̹̫͓̣͖͈̐ͬg̢͕̘͙o̪͆̏ͥ͟(̖̭̟̱̰ͩ)̘̬͉̺̉̓ ̦͆́̚{ ̶̪͙̹͈ͮͧ̋ͪͤͅĜ͔̙̉͢ ̝̯ͭ̈́͘<̨͊̂͋̎ ̤͇̼̝͔͇ͯ̑̋ͫ̾͐̚(ͨͪͦ̈̈́ͥ4͍͗̆2̲̞̦̳̖͡)͖͇̟̥ͮ͘ ̺̖͙̘̳͛̐̊͊>̼͍̘̦͖̎ ̧̘̻̭͉̺g̟͓̑ͦ̌̃(̪ͬͪͤ̎̉͘ȉ̮̥͖́n̸̝̪̗̯͇̓̈́̀̔̄̍́t͓̟͍ͨͪ(̰͈̻͎̣͉̀̿̈͑)̝͚̆̃̇)̠̃;̺͎̙̰̈́̏̚͘ ̶̜͍̠̼ͬ}̡̤̰̮̳͈̌͛ͤ̈́ A function accepting a function pointer? Stooooop!
- Tyr42 10y agoYou can just do class B; class A { B* _b; }; and it'll be happy.
- green7ea 10y agoIt can easily be done by declaring a prototype of B: // file: A.h class B; class A { B* _b; }; // file: B.h class B { A* _a; };