friend class doesn't work when I put in namespace?
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
friend class doesn't work when I put in namespace?
Here is a simple c++ program that demonstrates friend classes:
Code:
class A {
friend class B;
private:
int var;
};
class B {
public:
int GetVar() { return myA.var; }
private:
A myA;
};
int main() {}
The above code compiles just fine. However, when I put class A into a namespace, like so:
Code:
namespace wk {
class A {
friend class B;
private:
int var;
};
} // namespace wk
class B {
public:
int GetVar() { return myA.var; }
private:
wk::A myA;
};
int main() {}
The above code does not compile. I get the following error message:
Code:
wk@ALPHA:~/cprog$ g++ -o tmp tmp.cpp
tmp.cpp: In member function 'int B::GetVar()':
tmp.cpp:7: error: 'int wk::A::var' is private
tmp.cpp:14: error: within this context
I can put class A in a namespace, but only if I make var public, like so:
Code:
namespace wk {
class A {
public:
int var;
};
} // namespace wk
class B {
public:
int GetVar() { return myA.var; }
private:
wk::A myA;
};
int main() {}
The above code compiles just fine, without error.
Does anyone know why this is? It looks like using namespaces nullifies friend classes. I couldn't find any mention of this in any of the c++ references that I found on the internet. Is there a way to keep A.var private, while keeping it in a namespace?
Last edited by Winter Knight; 12-12-2007 at 02:24 AM.
Only learning C++ myself, but I found if you stick a forward declaration of class B at the top of your file it will compile, scope issue maybe ?
Code:
class B;
namespace wk {
class A {
friend class B;
private:
int var;
};
} // namespace wk
class B {
public:
int GetVar() { return myA.var; }
private:
wk::A myA;
};
int main() {}
I just downloaded, installed, and tried g++-3.4 on your version of the program, and I get the same results as you. I wonder which one is correct. I still don't understand why my original doesn't compile. Their shouldn't be a scope issue, because the code inside a block, such as the "wk" namespace, should be able to see outside of it's block. It's just that nobody should be able to see inside without fully qualifying (which I do).
This might be a compiler bug, but I'm not sure. I've thought that before, and then someone comes along and shows me my error.
class B;
namespace wk {
class A {
friend class ::B;
private:
int var;
};
} // namespace wk
class B {
public:
int GetVar() { return myA.var; }
private:
wk::A myA;
};
int main() {}
ntubski reply is correct and it is due to scope(namespace issue), by leaving out the scope operator you are saying the class is in the same namespace as the other class. ie
Code:
namespace BAR{ class Bar{};}
class Bar{};
namespace FOO{
class Bar{};
class Foo
{
friend class Bar;//says Bar is really FOO::Bar
firend class ::Bar;//says Bar is a member of the global namespace
firend class BAR::Bar;//says Bar is a member of the BAR namespace
}
;
}
plus you have to forward declare the class.
Last edited by dmail; 12-12-2007 at 10:43 AM.
Reason: added class FOO::Bar to show the usefulness of it
OK. Thanks. I get the part about scope. But why do you have to forward declare only if you use a namespace, but not if the two classes are in the same namespace?
For example, this works:
Code:
class A {
friend class B;
private:
int var;
};
class B {
public:
int GetVar() { return myA.var; }
private:
A myA;
};
int main() {}
But this doesn't:
Code:
namespace wk {
class A {
friend class ::B;
private:
int var;
};
} // namespace wk
class B {
public:
int GetVar() { return myA.var; }
private:
wk::A myA;
};
int main() {}
In the second example, of course, it works if I forward declare class B.
You have to declare friendship to the function in the namespace, not
to a non-existent global one.
...
Just to be accurate, you'll get a bunch of errors since
1) mynamespace is undeclared at this point
2) the Bar declaration has no return value
This is a good example (one of many) why I think C++ is a *terrible* language for beginners - there are just too many subtle "surprises" for anybody but advanced C++ programmers to have to deal with.
Thanks for the links, paulsm4. It helped me understand the situation a lot. Here is an especially interesting quote from the second link:
"The wording in the standard regarding the handling of names declared in unqualified friend declarations is unclear and, in certain cases, clearly incorrect."
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.