LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-15-2011, 11:24 PM   #1
Jusctsch
LQ Newbie
 
Registered: Oct 2010
Posts: 5

Rep: Reputation: 0
Does making a class a 'friend' make the class' member classes 'friends'?


Based on previous compiles of my particular code, I would assume yes, but I've been fighting an issue where I keep getting privacy errors in this case.

Code:
class Cat;

class Vase
{

   private:
      friend class Cat;
      void smash();
};

class Cat
{
   private:
   class Tail
   {
       void wag(Vase *a){ a->smash();}
   };
};
Would this be the error as follows?:

error: `void Vase::smash()' is private

If that doesn't work, what should be done?

Thanks

Last edited by Jusctsch; 11-15-2011 at 11:25 PM.
 
Old 11-16-2011, 12:24 AM   #2
firstfire
Member
 
Registered: Mar 2006
Location: Ekaterinburg, Russia
Distribution: Debian, Ubuntu
Posts: 709

Rep: Reputation: 428Reputation: 428Reputation: 428Reputation: 428Reputation: 428
Hi.

Maybe you should put 'public:' just before 'void wag(...)'?
Code:
#include <iostream>
using namespace std;

class Cat;

class Vase
{

   private:
      friend class Cat;
      void smash(){ cout << "smash" << endl; };
};

class Cat
{
   public:
   Cat()
   {
	Tail t;
	Vase v;
	t.wag(&v);
   }
   private:
   class Tail
   {
      public:
       void wag(Vase *a){ a->smash(); }
   };
};
int main()
{
	Cat c;
	return 0;
}
This code compiles fine and prints 'smash', thus private function Vase::smash() is available inside Tail class.
 
Old 11-16-2011, 12:31 AM   #3
corp769
LQ Guru
 
Registered: Apr 2005
Location: /dev/null
Posts: 5,818

Rep: Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007Reputation: 1007
Before, I really wanted to reply with the following, without even fully looking at the code:
"Just make it public."

Guess I was right
 
Old 11-16-2011, 12:51 AM   #4
SigTerm
Member
 
Registered: Dec 2009
Distribution: Slackware 12.2
Posts: 379

Rep: Reputation: 234Reputation: 234Reputation: 234
Quote:
Originally Posted by Jusctsch View Post
Does making a class a 'friend' make the class' member classes 'friends'?
No.
Quote:
Originally Posted by C++Standard
ISO/IEC 14882:2003
11.4 [class.friend]
...
Declaring a class to be a friend implies that the names of private and protected members from the class
granting friendship can be accessed in declarations of members of the befriended class. [Note: this means
that access to private and protected names is also granted to member functions of the friend class (as if the
functions were each friends) and to the static data member definitions of the friend class. This also means
that private and protected type names from the class granting friendship can be used in the base-clause of a
nested class of the friend class. However, the declarations of members of classes nested within the friend
class cannot access the names of private and protected members from the class granting friendship.
Also,
because the base-clause of the friend class is not part of its member declarations, the base-clause of the
friend class cannot access the names of the private and protected members from the class granting friend-
ship. For example,
Quote:
Originally Posted by Jusctsch View Post
Based on previous compiles of my particular code, I would assume yes, but I've been fighting an issue where I keep getting privacy errors in this case.
You should use "friend" only when absolutely necessary. Your example doesn't need "friends". You also don't need private functions in this particular case.
 
Old 11-16-2011, 04:24 AM   #5
firstfire
Member
 
Registered: Mar 2006
Location: Ekaterinburg, Russia
Distribution: Debian, Ubuntu
Posts: 709

Rep: Reputation: 428Reputation: 428Reputation: 428Reputation: 428Reputation: 428
Just found this thread. As I understand, there are no single opinion about this problem in C++ standard currently in use, but newer standard C++0X seems to allow that access.
 
Old 11-16-2011, 04:31 AM   #6
SigTerm
Member
 
Registered: Dec 2009
Distribution: Slackware 12.2
Posts: 379

Rep: Reputation: 234Reputation: 234Reputation: 234
Quote:
Originally Posted by firstfire View Post
Just found this thread. As I understand, there are no single opinion about this problem in C++ standard currently in use, but newer standard C++0X seems to allow that access.
  1. The quote I provided is from 2003 standard.
  2. There's no "standard currently in use". Different compiler may support different standard. There is, however, most recent standard.
  3. C++0x is a draft. The proper name for most recent standard is C++11.
 
Old 11-16-2011, 09:31 AM   #7
Jusctsch
LQ Newbie
 
Registered: Oct 2010
Posts: 5

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by SigTerm View Post
  1. The quote I provided is from 2003 standard.
  2. There's no "standard currently in use". Different compiler may support different standard. There is, however, most recent standard.
  3. C++0x is a draft. The proper name for most recent standard is C++11.
I've seen different behavior on different compilers unfortunately.
Code:
class Cat;

class Vase
{

   private:
      friend class Cat;
      friend class Cat::Tail;
      void smash();
};

class Cat
{
   private:
   class Tail
   {
       private:
       void wag(Vase *a){ a->smash();}
   };
};
Couldn't this also be a legal statement? I'm not a fan of opening gaping holes when a small peephole would work just fine.
Side topic, but is 'friend' perceived as being a huge hack in C++?

EDIT
Code:
#include <iostream>
using namespace std;

class Cat;

class Vase
{

   private:
      friend class Cat;
      void smash(){ cout << "smash" << endl; };
};

class Cat
{
   public:
   Cat()
   {
	Tail t;
	Vase v;
	t.dostuff(&v);
   }
   private:
   class Tail
   {
      public:
	  void dostuff(Vase *a){wag(a);}
      private:
       void wag(Vase *a){ a->smash(); }
   };
};
int main()
{
	Cat c;
	return 0;
}
This compiles legally. On running the resulting binary, the member Tail is able to 'smash' the Vase. The member (Tail) is calling the private function of the class (Vase) who had friended the parent class (Cat).

Quote:
$ g++ --version
g++.exe (GCC) 4.4.3
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ g++ friends_who_have_member_classes.cpp -o test

$ ./test
smash
Is this what people would expect?

Last edited by Jusctsch; 11-16-2011 at 10:02 AM.
 
Old 11-17-2011, 07:58 PM   #8
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,632
Blog Entries: 4

Rep: Reputation: 3931Reputation: 3931Reputation: 3931Reputation: 3931Reputation: 3931Reputation: 3931Reputation: 3931Reputation: 3931Reputation: 3931Reputation: 3931Reputation: 3931
My not-so-good anymore eyes (shaddup... it will happen to you, too!) are starting to glaze-over here.

If you're starting to write code that ventures into this kind of esoterica in the definition (past or present or future) of the C++ language ...

... then you need to be advised from the outset that "you are in the process of making what will one day be regarded as a package of unmaintainable sh*t."

Please, hear me out.

If there are but two things that are absolute constants in the world of software, they are these:
  1. Businesses change.
  2. Software doesn't.
It would probably be more accurate to say that, since at the end of the day the software in question m-u-s-t somehow be caused to match the business (the software is, after all, much too expensive and much too business-critical to throw away ...), "it will be dragged, kicking and screaming, across the transom of change," and it will probably fall completely apart in the process.

When you are writing software... "please, don't be clever." Every time you avail yourself of features such as "friends," you are (whether you realize the long-term implications of your actions or not ...) creating a wicked and utterly intractable functional dependency between the two that one day just might be regarded as the relationship between Harry Potter and Lord Voldemort.

I'll step off my soapbox now. But please, mark my words. I've spent most of my thirty-plus year career untangling what was once "clever" software. And sometimes it feels just like disarming a most-delicate bomb. The most noble of intentions, practiced by obviously skilled and knowledgeable programmers, can nevertheless turn into ... scrap. And, if I may bluntly say so, "the more 'clever' it is, the more likely it is to be unsalvageable." (And let no one call me a Luddite, because you would not know whereof you speak. Just sayin' ...)

The guy who runs the junk-yard does have a valid opinion with regard to cars.

Last edited by sundialsvcs; 11-17-2011 at 08:02 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Class inheritance terminology: super-classes or base classes? 2ck Programming 6 07-20-2011 10:17 AM
Need details on the classes available in the /sys/class folder on RHEL and SuSE. PrasannaKumariMS Linux - General 1 05-03-2011 10:49 AM
[SOLVED] C++ Initialize Class Member Variables of Another Class Type mirlin510 Programming 9 04-13-2011 11:46 AM
friend class doesn't work when I put in namespace? Winter Knight Programming 10 12-13-2007 12:57 PM
C++ templated Node class: pointers to different instantated class types jhwilliams Programming 3 08-20-2007 06:20 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 12:52 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration