Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Copy Inherited Objects

Reply
Thread Tools

Copy Inherited Objects

 
 
timid
Guest
Posts: n/a
 
      05-17-2008
I'm attempting to learn how to use inheritance in C++, the following
program should print the word 'Orange' on the screen but it prints
'Apple' instead. Can someone explain what is wrong?

#include <iostream>

class Fruit
{
public:
virtual const char* get_name() {return "(nothing)";}
};

class Apple: public Fruit
{
public:
const char* get_name() {return "Apple";}
};

class Orange: public Fruit
{
const char* get_name() {return "Orange";}
};

int main()
{
std::cout << "Test inheritation" << std::endl;

Fruit *myfruit1 = new Apple();
Fruit *myfruit2 = new Orange();
Fruit *myfruit3 = new Apple();

std::cout << "myfruit1 = " << myfruit1->get_name() <<
std::endl; // Prints "Apple"
std::cout << "myfruit2 = " << myfruit2->get_name() <<
std::endl; // Prints "Orange"
std::cout << "myfruit3 = " << myfruit3->get_name() <<
std::endl; // Prints "Apple"

// The following does not work
std::cout << "Now change myfruit3 from Apple to Orange..." <<
std::endl;
*myfruit3 = *myfruit2;

// Prints "Apple" but should print "Orange"
std::cout << "myfruit3 = " << myfruit3->get_name() << std::endl;

// Wait for a keypress
std::cin.get();

delete myfruit1;
delete myfruit2;
delete myfruit3;
}
 
Reply With Quote
 
 
 
 
Christian Hackl
Guest
Posts: n/a
 
      05-17-2008
timid wrote:

> #include <iostream>
>
> class Fruit
> {
> public:
> virtual const char* get_name() {return "(nothing)";}


Use std::string rather than char*.

Also, a function such as "get_name" should usually be declared const.

> };
>
> class Apple: public Fruit
> {
> public:
> const char* get_name() {return "Apple";}
> };
>
> class Orange: public Fruit
> {
> const char* get_name() {return "Orange";}
> };
>
> int main()
> {
> std::cout << "Test inheritation" << std::endl;
>
> Fruit *myfruit1 = new Apple();
> Fruit *myfruit2 = new Orange();
> Fruit *myfruit3 = new Apple();
>
> [...]
>
> // The following does not work
> std::cout << "Now change myfruit3 from Apple to Orange..." <<
> std::endl;
> *myfruit3 = *myfruit2;


* derefences the pointer, yielding the object it's pointing to.
Consequently, in your example you don't assign the _pointers_, you
assign the _objects_ they are pointing to. That's a huge difference.
Assigning an Orange to an Apple obviously does not do anything because
you did not specify anything to happen in case of such an assignment.
The invisible assignment operator automatically generated by the
compiler is empty. In other words, the Apple is completely unaffected by
the operation.


If you want to assign a pointer to another pointer, you have to write:

myfruit3 = myfruit2;

However, in your program this would have disastrous results because you
would lose the old value of myfruit3, which means you cannot delete your
second Apple anymore. (You'd have to save the old value somewhere, for
example in a temporary pointer variable.)

What do you try to achieve by having myfruit3 point to a different object?


--
Christian Hackl
 
Reply With Quote
 
 
 
 
timid
Guest
Posts: n/a
 
      05-17-2008
On May 17, 10:49 pm, Christian Hackl <ha...@sbox.tugraz.at> wrote:
> timid wrote:
> > #include <iostream>

>
> > class Fruit
> > {
> > public:
> > virtual const char* get_name() {return "(nothing)";}

>
> Use std::string rather than char*.
>
> Also, a function such as "get_name" should usually be declared const.
>
>
>
> > };

>
> > class Apple: public Fruit
> > {
> > public:
> > const char* get_name() {return "Apple";}
> > };

>
> > class Orange: public Fruit
> > {
> > const char* get_name() {return "Orange";}
> > };

>
> > int main()
> > {
> > std::cout << "Test inheritation" << std::endl;

>
> > Fruit *myfruit1 = new Apple();
> > Fruit *myfruit2 = new Orange();
> > Fruit *myfruit3 = new Apple();

>
> > [...]

>
> > // The following does not work
> > std::cout << "Now change myfruit3 from Apple to Orange..." <<
> > std::endl;
> > *myfruit3 = *myfruit2;

>
> * derefences the pointer, yielding the object it's pointing to.
> Consequently, in your example you don't assign the _pointers_, you
> assign the _objects_ they are pointing to. That's a huge difference.
> Assigning an Orange to an Apple obviously does not do anything because
> you did not specify anything to happen in case of such an assignment.
> The invisible assignment operator automatically generated by the
> compiler is empty. In other words, the Apple is completely unaffected by
> the operation.
>
> If you want to assign a pointer to another pointer, you have to write:
>
> myfruit3 = myfruit2;
>
> However, in your program this would have disastrous results because you
> would lose the old value of myfruit3, which means you cannot delete your
> second Apple anymore. (You'd have to save the old value somewhere, for
> example in a temporary pointer variable.)
>
> What do you try to achieve by having myfruit3 point to a different object?
>
> --
> Christian Hackl


Thank's for the help so far, it would appear that I need to learn a
lot more.

I'm going to try & rewrite this program so it'll work.
 
Reply With Quote
 
Marcel Müller
Guest
Posts: n/a
 
      05-18-2008
Hi!

Christian Hackl schrieb:
>> class Fruit
>> {
>> public:
>> virtual const char* get_name() {return "(nothing)";}

>
> Use std::string rather than char*.


Normally I would agree, but in case of /const/ char* there is usually no
problem. Only the use of char* for strings in C++ applications is nearly
always a risk. On the other hand, using std::string for this (and
similar) purposes is a significant runtime overhead. Only if you already
have a std::string it is more advisable to return std::string, or if
this causes no threading or aliasing problem const std::string&.

> Also, a function such as "get_name" should usually be declared const.


That's obviously true.


> If you want to assign a pointer to another pointer, you have to write:
>
> myfruit3 = myfruit2;
>
> However, in your program this would have disastrous results because you
> would lose the old value of myfruit3, which means you cannot delete your
> second Apple anymore. (You'd have to save the old value somewhere, for
> example in a temporary pointer variable.)
>
> What do you try to achieve by having myfruit3 point to a different object?


I think the OP is seeking for something like a clone method.


Marcel
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      05-18-2008
On 17 mai, 23:11, timid <visicalcena...@googlemail.com> wrote:
> I'm attempting to learn how to use inheritance in C++, the
> following program should print the word 'Orange' on the screen
> but it prints 'Apple' instead. Can someone explain what is
> wrong?


> #include <iostream>


> class Fruit
> {
> public:
> virtual const char* get_name() {return "(nothing)";}
> };


> class Apple: public Fruit
> {
> public:
> const char* get_name() {return "Apple";}
> };


> class Orange: public Fruit
> {
> const char* get_name() {return "Orange";}
> };


> int main()
> {
> std::cout << "Test inheritation" << std::endl;


> Fruit *myfruit1 = new Apple();
> Fruit *myfruit2 = new Orange();
> Fruit *myfruit3 = new Apple();


> std::cout << "myfruit1 = " << myfruit1->get_name() <<
> std::endl; // Prints "Apple"
> std::cout << "myfruit2 = " << myfruit2->get_name() <<
> std::endl; // Prints "Orange"
> std::cout << "myfruit3 = " << myfruit3->get_name() <<
> std::endl; // Prints "Apple"


> // The following does not work
> std::cout << "Now change myfruit3 from Apple to Orange..." <<
> std::endl;
> *myfruit3 = *myfruit2;


And what do you expect this to do? You cannot change the type
of an existing object. In general, when inheritence is
involved, you don't support assignment and copy.

> // Prints "Apple" but should print "Orange"
> std::cout << "myfruit3 = " << myfruit3->get_name() << std::endl;


No. Should print "Apple". But a lot of typical implementations
of the assignment operator (for more complicated types) will
result in undefined behavior. The base class for an inheritence
hierarchy should normally forbid assignment, so that the
situation can't arrive, even accidentally.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      05-18-2008
On 18 mai, 11:29, Marcel Müller <news.5.ma...@spamgourmet.com> wrote:
> I think the OP is seeking for something like a clone method.


Or the letter/envelope idiom. Or perhaps just simply some
information on OO design; he hasn't really expressed a concrete
need for assignment.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
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
'Class.inherited' v. 'inherited' syntax inside Class 7stud -- Ruby 11 11-09-2007 06:45 PM
class objects, method objects, function objects 7stud Python 11 03-20-2007 06:05 PM
what is Deep Copy, shallow copy and bitwises copy.? saxenavaibhav17@gmail.com C++ 26 09-01-2006 09:37 PM
Copy constructor: why can't I copy objects as if they were structs? rdc02271 C++ 24 12-27-2005 12:38 PM
is dict.copy() a deep copy or a shallow copy Alex Python 2 09-05-2005 07:01 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57