|
From: Rune Allnor on 28 Jun 2008 07:58 Hi all. I would like to implement a hierarchy of classes to print some messages to the screen. At present I would like to use a base class with default behaviour, which then might be overloaded to handle application-specific situations. One relevant scenario is to use some GUI toolkit to print the message in some sort of graphics widget. Below is an outline of my naive idea to accomplish this. The base class defines the default interface. The compound class is some class which contains an internal class, compond::derived, which is intended to implement GUI-specific behaviour by accessing internal methods in the widget. In a sense, the derived class acts as a backdoor ito the compound class. The general idea works, as the free function accepts arguments of both base type and compound::derived type. However, the crux of the idea doesn't work, as the compound::derived::print() method will not compile if one tries to access the compound::i variable (see the tagged line). Is there a way to make this idea work? Is there some other pattern which is better suited to achieve the end goal? I see no problems achieving this by declaring a derived class outside compund which is declared to be a friend of compound. But then, I have some very vague recollection of having read somewhere in ancient pre-history (some time in the mid '90s) that the friend keyword is a bit dangerous as it grants outsiders access to private parts, and is thus best avoided. Is this view still valid? Rune ////////////////////////////////////////////////////////////////////////////////////////// #include <iostream> class base{ public: virtual void print(){std::cout << "Base class" << std::endl;}; }; void print(base& b) { std::cout << "Free function: "; b.print(); }; class compound{ private: int i; public: compound(){i=1;}; class derived: public base{ public: virtual void print(){std::cout << "Derived class"; std::cout /*<< i */ << std::endl;}; //<<<<< ======= }; derived compound_backdoor; void print(){compound_backdoor.print();}; }; int main(int argc, char* argv[]) { base b; b.print(); print(b); compound c; c.compound_backdoor.print(); print(c.compound_backdoor); return 0; } -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Jim Langston on 29 Jun 2008 05:13 "Rune Allnor" <allnor(a)tele.ntnu.no> wrote in message news:b12a5075-7e71-414f-9f5d-656f6467a0d7(a)j22g2000hsf.googlegroups.com... > Hi all. > > I would like to implement a hierarchy of classes to print > some messages to the screen. At present I would like to > use a base class with default behaviour, which then might > be overloaded to handle application-specific situations. > One relevant scenario is to use some GUI toolkit to print > the message in some sort of graphics widget. > > Below is an outline of my naive idea to accomplish this. > The base class defines the default interface. The compound > class is some class which contains an internal class, > compond::derived, which is intended to implement > GUI-specific behaviour by accessing internal methods > in the widget. In a sense, the derived class acts as a > backdoor ito the compound class. > > The general idea works, as the free function accepts > arguments of both base type and compound::derived > type. > > However, the crux of the idea doesn't work, as the > compound::derived::print() method will not compile if > one tries to access the compound::i variable (see the > tagged line). > > Is there a way to make this idea work? > Is there some other pattern which is better suited > to achieve the end goal? > > I see no problems achieving this by declaring a > derived class outside compund which is declared > to be a friend of compound. But then, I have some > very vague recollection of having read somewhere > in ancient pre-history (some time in the mid '90s) > that the friend keyword is a bit dangerous as it > grants outsiders access to private parts, and is > thus best avoided. > > Is this view still valid? > > Rune > > ////////////////////////////////////////////////////////////////////////////////////////// > #include <iostream> > > class base{ > public: > virtual void print(){std::cout << "Base class" << std::endl;}; > }; > > void print(base& b) > { > std::cout << "Free function: "; > b.print(); > }; > > class compound{ > private: > int i; > public: > compound(){i=1;}; > > class derived: public base{ > public: > virtual void print(){std::cout << "Derived class"; > std::cout /*<< i */ << std::endl;}; //<<<<< As far as the compiler is concerned, which "i" is this refering to? There is no "i" in scope. No global i, no i inside of the class base, derived or in the function print. Which is why compilation will fail. An instance of compound and an instance of derived are not linked in any real sense. compound contains an instance of class derived, but that's the extent of it. If you want derived to "see" a private variable of class compound a few things would have to happen. 1. derived would have to be a friend to compound. 2. print would have to know which instance of compound to look at. So it would need a pointer or a reference to an instance of compound someway ( on initialzation or pass it to print, or whatever). Consider something like this: class compound{ private: int i; } class derived: public base{ virtual void print() { std:;cout << i << std::endl; } }; You wouldn't expect that to compile, would you (barring any syntax errors on my part). Why not? because print has no relation to compound. Making a class declared isnide of another class doesn't really change this. There is no magic going on linking instances of the objects. I hope this points you to where the problem lies. > ======= > }; > derived compound_backdoor; > void print(){compound_backdoor.print();}; > }; > > int main(int argc, char* argv[]) > { > base b; > b.print(); > print(b); > compound c; > c.compound_backdoor.print(); > print(c.compound_backdoor); > return 0; > } -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Rune Allnor on 29 Jun 2008 05:28 On 29 Jun, 00:58, Rune Allnor <all...(a)tele.ntnu.no> wrote: > Hi all. > > I would like to implement a hierarchy of classes to print > some messages to the screen. At present I would like to > use a base class with default behaviour, which then might > be overloaded to handle application-specific situations. Never mind - the solution popped into my mind in the very moment the post was sent: Use multiple inheritance. > I have some > very vague recollection of having read somewhere > in ancient pre-history (some time in the mid '90s) > that the friend keyword is a bit dangerous as it > grants outsiders access to private parts, and is > thus best avoided. > > Is this view still valid? I can't find the C++ books I used 12 years ago, so I am unable to dig up the exact phrasings, but it would have been from one or both of these books: http://www.amazon.com/Object-Oriented-Programming-Raimund-K-Ege/dp/0122329325/ref=sr_1_1?ie=UTF8&s=books&qid=1214728556&sr=8-1 http://www.amazon.com/Waite-Groups-C-Programming-Second/dp/B001AI5CQS/ref=sr_1_9?ie=UTF8&s=books&qid=1214728591&sr=1-9 Is there a different attitude to friend classes these days? Rune -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
|
Pages: 1 Prev: variable function in a template ? Next: Comment on my adapter concept |