Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Cline/Lomow Book (Original) FAQ # 158

Reply
Thread Tools

Cline/Lomow Book (Original) FAQ # 158

 
 
Tom
Guest
Posts: n/a
 
      12-15-2005
FAQ 158 is about correct usage of OO. I am struggling to understand
how the correct function is selected. Three derived classes from base
class "Printer2". Where is the logic that selects from the three
over-rides? That small decoration "p" in the next to last line of code
seems to be the key. This rookie just doesn't 'get it'. Thanks for any
help.

Below is a copy of the FAQ 158 program:

=========================================

class Printer2 {
public :
virtual ~Printer2( ) { }
virtual void italics(const char* s) = 0;
};

class EpsonPrinter2 : public Printer2 {
public :
virtual void intalics(const char* s)
{ cout << esc << "i+" << s << esc << "i-"; }
};

class ProprinterPrinter2 : public Printer2 {
public :
virtual void intalics(const char* s)
{ cout << esc << "[i" << s << esc << "[n"; }
};

class StarPrinter2 : public Printer2 {
public :
virtual void intalics(const char* s)
{ cout << esc << "x" << s << esc << "y"; }
};

void
printUsingItalics ( Printer2& p, const char* s)
{
p.italics(s);
}
 
Reply With Quote
 
 
 
 
Neelesh Bodas
Guest
Posts: n/a
 
      12-15-2005

Tom wrote:
> FAQ 158 is about correct usage of OO. I am struggling to understand
> how the correct function is selected. Three derived classes from base
> class "Printer2". Where is the logic that selects from the three
> over-rides? That small decoration "p" in the next to last line of code
> seems to be the key. This rookie just doesn't 'get it'. Thanks for any
> help.
>
> Below is a copy of the FAQ 158 program:
>
> =========================================
>
> class Printer2 {
> public :
> virtual ~Printer2( ) { }
> virtual void italics(const char* s) = 0;
> };
>
> class EpsonPrinter2 : public Printer2 {
> public :
> virtual void intalics(const char* s)
> { cout << esc << "i+" << s << esc << "i-"; }
> };
>
> class ProprinterPrinter2 : public Printer2 {
> public :
> virtual void intalics(const char* s)
> { cout << esc << "[i" << s << esc << "[n"; }
> };
>
> class StarPrinter2 : public Printer2 {
> public :
> virtual void intalics(const char* s)
> { cout << esc << "x" << s << esc << "y"; }
> };
>
> void
> printUsingItalics ( Printer2& p, const char* s)
> {
> p.italics(s);
> }


Since italics is a virtual function, it is bound dynamically. In other
words, the exact version of italics is selected from the actual class
held by the reference p.

 
Reply With Quote
 
 
 
 
marcas
Guest
Posts: n/a
 
      12-15-2005
Tom schrieb:
> FAQ 158 is about correct usage of OO. I am struggling to understand
> how the correct function is selected. Three derived classes from base
> class "Printer2". Where is the logic that selects from the three
> over-rides? That small decoration "p" in the next to last line of code
> seems to be the key. This rookie just doesn't 'get it'. Thanks for any
> help.
>


Hi,

http://www.parashift.com/c++-faq-lit...functions.html

has a good explanation [see 20.4]

regards marcas
 
Reply With Quote
 
Tom
Guest
Posts: n/a
 
      12-15-2005
On 15 Dec 2005 00:22:27 -0800, "Neelesh Bodas"
<(E-Mail Removed)> wrote:

>
>Tom wrote:
>> FAQ 158 is about correct usage of OO. I am struggling to understand
>> how the correct function is selected. Three derived classes from base
>> class "Printer2". Where is the logic that selects from the three
>> over-rides? That small decoration "p" in the next to last line of code
>> seems to be the key. This rookie just doesn't 'get it'. Thanks for any
>> help.
>>
>> Below is a copy of the FAQ 158 program:
>>
>> =========================================
>>
>> class Printer2 {
>> public :
>> virtual ~Printer2( ) { }
>> virtual void italics(const char* s) = 0;
>> };
>>
>> class EpsonPrinter2 : public Printer2 {
>> public :
>> virtual void intalics(const char* s)
>> { cout << esc << "i+" << s << esc << "i-"; }
>> };
>>
>> class ProprinterPrinter2 : public Printer2 {
>> public :
>> virtual void intalics(const char* s)
>> { cout << esc << "[i" << s << esc << "[n"; }
>> };
>>
>> class StarPrinter2 : public Printer2 {
>> public :
>> virtual void intalics(const char* s)
>> { cout << esc << "x" << s << esc << "y"; }
>> };
>>
>> void
>> printUsingItalics ( Printer2& p, const char* s)
>> {
>> p.italics(s);
>> }

>
>Since italics is a virtual function, it is bound dynamically. In other
>words, the exact version of italics is selected from the actual class
>held by the reference p.


Thanks for the reply Neelesh. I am definately struggling in the
transition to OO. Some of the examples within "C++ FAQs" are far more
advanced than my current skill level. The examples I guess are not
complete blocks of code? In particular the main( ) is missing? Your
response made me reread chapter #23 on references and referents. (130
pages deeper into the book. I have read it cover-to-cover and will
have to repeatedly it seems.)

So to make the code complete ... one needs to add something along the
following lines?

main ( )
{
StarPrinter2 p; // Creating A Derived Object
// Of Type StarPrinter2
char textString[] = "I have a dream to learn OO.";
printUsingItalics( p , textString );
}
 
Reply With Quote
 
Neelesh Bodas
Guest
Posts: n/a
 
      12-15-2005
Tom wrote:
>
> So to make the code complete ... one needs to add something along the
> following lines?
>
> main ( )
> {
> StarPrinter2 p; // Creating A Derived Object
> // Of Type StarPrinter2
> char textString[] = "I have a dream to learn OO.";
> printUsingItalics( p , textString );
> }


I am really not sure. IIRR, this involves a problem of "slicing". You
are actually passing a reference to derived class, but the function
prototype expects a reference to base class.

Better is to do this :

Printer2 *p = new StarPrinter2;
char textString[] = "I have a dream to learn OO.";
printUsingItalics( *p , textString );

But as I said, I am not sure about this slicing thing (I know that it
happens when you have pointers in place of references)

 
Reply With Quote
 
deane_gavin@hotmail.com
Guest
Posts: n/a
 
      12-15-2005

Neelesh Bodas wrote:

> Tom wrote:
> >
> > So to make the code complete ... one needs to add something along the
> > following lines?
> >
> > main ( )
> > {
> > StarPrinter2 p; // Creating A Derived Object
> > // Of Type StarPrinter2
> > char textString[] = "I have a dream to learn OO.";
> > printUsingItalics( p , textString );
> > }

>
> I am really not sure. IIRR, this involves a problem of "slicing". You
> are actually passing a reference to derived class, but the function
> prototype expects a reference to base class.


That's not a problem. You don't get slicing when you pass by reference
like that. You get slicing when you pass a derived object by *value* to
a function expecting a base object. Have you ever thrown an exception
derived from std::exception then caught a std::exception&. It works.

> Better is to do this :
>
> Printer2 *p = new StarPrinter2;
> char textString[] = "I have a dream to learn OO.";
> printUsingItalics( *p , textString );


Dynamic allocation and pointers are not necessary to avoid slicing. So,
as ever, if you don't need to manually control the lifetime of the
object, don't use dynamic allocation.

Gavin Deane

 
Reply With Quote
 
mlimber
Guest
Posts: n/a
 
      12-15-2005
Neelesh Bodas wrote:
> Tom wrote:
> >
> > So to make the code complete ... one needs to add something along the
> > following lines?
> >
> > main ( )
> > {
> > StarPrinter2 p; // Creating A Derived Object
> > // Of Type StarPrinter2
> > char textString[] = "I have a dream to learn OO.";
> > printUsingItalics( p , textString );
> > }

>
> I am really not sure. IIRR, this involves a problem of "slicing". You
> are actually passing a reference to derived class, but the function
> prototype expects a reference to base class.


Incorrect. Passing an object by value might slice it, but passing by
pointer OR by reference will both produce correct polymorphic behavior
and without chance of slicing. See these FAQs:

http://www.parashift.com/c++-faq-lit....html#faq-31.1
http://www.parashift.com/c++-faq-lit....html#faq-31.8

> Better is to do this :
>
> Printer2 *p = new StarPrinter2;
> char textString[] = "I have a dream to learn OO.";
> printUsingItalics( *p , textString );
>
> But as I said, I am not sure about this slicing thing (I know that it
> happens when you have pointers in place of references)


Better at least to use std::auto_ptr (or boost::scoped_ptr,
boost::shared_ptr, etc.) if you're going to use new. The OP's code is
better in my opinion since it avoids dynamic allocation altogether when
it is unnecessary.

Cheers! --M

 
Reply With Quote
 
Artie Gold
Guest
Posts: n/a
 
      12-15-2005
Neelesh Bodas wrote:
> Tom wrote:
>
>>So to make the code complete ... one needs to add something along the
>>following lines?


What are you talking about?

Had you quoted the relevant portions of the originally supplied code,
this would all be clearer.

>>
>>main ( )
>>{
>> StarPrinter2 p; // Creating A Derived Object
>> // Of Type StarPrinter2

No, it's an attempt to instantiate an abstract base class -- which you
can't do.


>> char textString[] = "I have a dream to learn OO.";
>> printUsingItalics( p , textString );
>>}

>
>
> I am really not sure. IIRR, this involves a problem of "slicing". You
> are actually passing a reference to derived class, but the function
> prototype expects a reference to base class.
>
> Better is to do this :
>
> Printer2 *p = new StarPrinter2;


See above.

> char textString[] = "I have a dream to learn OO.";
> printUsingItalics( *p , textString );
>
> But as I said, I am not sure about this slicing thing (I know that it
> happens when you have pointers in place of references)
>

Please have *some* idea what you're doing before posting.

HTH,
--ag

--
Artie Gold -- Austin, Texas
http://goldsays.blogspot.com (new post 8/5)
http://www.cafepress.com/goldsays
"If you have nothing to hide, you're not trying!"
 
Reply With Quote
 
Neelesh Bodas
Guest
Posts: n/a
 
      12-15-2005

Artie Gold wrote:
> What are you talking about?
>
> Had you quoted the relevant portions of the originally supplied code,
> this would all be clearer.


My reply was w.r.t. the tom's post and I just quoted the "only relavent
portions from that". May be I quoted less, will take care in future.

>
> >>
> >>main ( )
> >>{
> >> StarPrinter2 p; // Creating A Derived Object
> >> // Of Type StarPrinter2

> No, it's an attempt to instantiate an abstract base class -- which you
> can't do.


StartPrinter2 is a derived class, derived from the base class Printer2
which is abstract. In other words, I am _not_ instantiating ABC - I am
simply creating an object of a derived class.

I believe that the confusion is due to the fact that OP has mis-spelled
italics as intalics in all derived classes. But looking at the context,
it was clear to me that OP actually meant italics at all these places.

>
>
> >> char textString[] = "I have a dream to learn OO.";
> >> printUsingItalics( p , textString );
> >>}

> >
> >
> > I am really not sure. IIRR, this involves a problem of "slicing". You
> > are actually passing a reference to derived class, but the function
> > prototype expects a reference to base class.
> >
> > Better is to do this :
> >
> > Printer2 *p = new StarPrinter2;

>
> See above.


Same applies here. I am _not_ instantiating an ABC.

> > char textString[] = "I have a dream to learn OO.";
> > printUsingItalics( *p , textString );
> >
> > But as I said, I am not sure about this slicing thing (I know that it
> > happens when you have pointers in place of references)
> >

> Please have *some* idea what you're doing before posting.


OK. Thanks for that. Will remember in future.

 
Reply With Quote
 
marcas
Guest
Posts: n/a
 
      12-15-2005
Artie Gold schrieb:

>>>
>>> main ( )
>>> {
>>> StarPrinter2 p; // Creating A Derived Object
>>> // Of Type StarPrinter2

>
> No, it's an attempt to instantiate an abstract base class -- which you
> can't do.
>
>


Hi,

it is true, that Printer2 is an abstract class. He makes an instance
of StarPrinter2, which is a non abstract class due to replacemant of the
pure virtual function. I think, that it is ok to assume that he meant
"italics" instead of "intalics".

regards marcas
 
Reply With Quote
 
 
 
Reply

Thread Tools

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 On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
NVidia 158.24's whql are out =?Utf-8?B?Q2FybG9z?= Windows 64bit 3 06-04-2007 09:48 AM
Nvidia 158.19 missing dll's Martin G Windows 64bit 4 05-23-2007 06:13 PM
NVidia Vista x64 158.18's 3rd. round? =?Utf-8?B?Q2FybG9z?= Windows 64bit 1 05-03-2007 06:48 PM
Nvidia 158.22 =?Utf-8?B?TWFyYXRvbm1hbm5lbg==?= Windows 64bit 3 05-02-2007 11:13 PM
New Nvidia 158.18 =?Utf-8?B?TWFyYXRvbm1hbm5lbg==?= Windows 64bit 11 04-18-2007 08:28 PM



Advertisments