[source lang=cpp]
class A;
class B;
class A {
friend int B::bfunc();
};
class B {
private:
class A a;
public:
int bfunc();
};
🔒 Locked
Circular Class definition
Advertisement
Original Post
Hello! I have two classes, one of which instantiates the other, and the other needs to define a function from the first as a friend: Since B contains an instance of A, B must obviously be declared after A. However, this means I can't define B's bfunc as a friend of A, since at that point bfunc is unknown. Is there some way of accomplishing this without declaring all of class B as a friend? Thanks! Zen
Kylotan has written a good article on this, you may take a look:
The article
The article
Quote:
Original post by lettel
Doesn't really make sense to me but the code below will compile.
*** Source Snippet Removed ***
'Tis very true, but that's cheating ;)
The question is if it's possible to resolve this circular definition without changing the basic structure of the classes. Ie, one class containing an instance to the other (NOT a pointer that is allocated in the constructor), and the other containing a similar reference (in this case a friend) that first requires the definition of the first class.
This is more of a conceptual challenge than an actual problem I have to work around: I'm just curious if there's some arcane C++ constructs that allow for this sort of circular referencing.
Zen
ps. Note that instancing one class in the other and vice versa makes no sense, since in that case a class would instance itself and its storage size be infinite. The problem here is conceptually possible, but may not be due to C++ syntax limitations.
The neatest way I could find was to make bfunc a non-member friend of B:
Enigma
#include <iostream>class A;class B;int bfunc(B & b);class A{ friend int bfunc(B &); int value; public: A() : value(0) { } void print() { std::cout << value << '\n'; }};class B{ private: A a; friend int bfunc(B &); public: int bfunc() { return ::bfunc(*this); } void print() { a.print(); }};int bfunc(B & b){ b.a.value = 7; return 0;}int main(){ B b; b.bfunc(); b.print();}Enigma
Quote:
Original post by haegarr
Not necessarily what you want, but
*** Source Snippet Removed ***
should fulfil the mentioned needs.
Quote:
Original post by ZQJ
If you add typedef B::A A; to haegarr's solution the syntax outside the header will be identical I think.
Interesting. You'd have to put class A in B's public space to avoid the class being private to B (ie so you can still instantiate it outside of B), but other than that I like it. Of course, you are out of luck if you add a class C similar to class B, though Enigma's solution would still work then.
Gotta say, I love these forums!
Zen
I'd just make B a friend of A. After all, if you can't trust the class writer/mantainer of class B to not do stupid things outside of B::bfunc(), how can you trust them to not do stupid things inside of B::bfunc()? But to each his own.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement