Array of object from varius subclasses

M

Marco

Hi all,

I have a base class and some subclasses; I need to define an array of
objects from these various subclasses. What I have is something like:

{

//I have a base class, something like:

class CPeople {
public:
virtual void Input() {printf("Inside CPeople::Input()\n");}
virtual void Show() {printf("Inside CPeople::Show()\n");}
};

//and some subclasses

class CMale : public CPeople {
public:
void Input() {};
void Show() {};
};

class CFemale : public CPeople {
public:
void Input() {printf("Inside CFemale::Input()\n");}
void Show() {printf("Inside CFemale::Show()\n");}
};

//Now I need an array of people...

CPeople MyArray[10];

//I create a CFemale Object...

CFemale temp;
temp.Input();

//I assign this object to an array element:

MyArray[1] = temp;
MyArray[1].Show();

return 0;
}
// I get :
// "Inside CFemale::Input()"
// "Inside CPeople::Show()"

So when I call MyArray[1].Show() the function called is the one
defined in the base class ( CPeople::Show() ).

What do I need to do to get the desired behaviour?

Thank you in advance...
Marco
 
M

Max M.

Marco said:
What do I need to do to get the desired behaviour?

You defined an array of CPeople objects. No matter what objects you assign
to them, they won't ever turn into anything else.

You only get polymorphic behaviour (which is what you supposedly meant by
"desired"), when you invoke an object's virtual member function
through a pointer or a reference to a base class.

For example:

CPeople* MyArray[10];

MyArray[1] = new CFemale;
MyArray[1]->Show();

Max
 
M

Marco

Hi Max,

Ok, I got it... Thank you!

Marco

Max M. said:
Marco said:
What do I need to do to get the desired behaviour?

You defined an array of CPeople objects. No matter what objects you assign
to them, they won't ever turn into anything else.

You only get polymorphic behaviour (which is what you supposedly meant by
"desired"), when you invoke an object's virtual member function
through a pointer or a reference to a base class.

For example:

CPeople* MyArray[10];

MyArray[1] = new CFemale;
MyArray[1]->Show();

Max
 
T

Thomas Wintschel

Marco said:
Hi Max,

Ok, I got it... Thank you!

Marco

Max M. said:
Marco said:
What do I need to do to get the desired behaviour?

You defined an array of CPeople objects. No matter what objects you assign
to them, they won't ever turn into anything else.

You only get polymorphic behaviour (which is what you supposedly meant by
"desired"), when you invoke an object's virtual member function
through a pointer or a reference to a base class.

For example:

CPeople* MyArray[10];

MyArray[1] = new CFemale;
MyArray[1]->Show();

Max

Note that Max made the change from an array of CPeople to an array of
CPeople*. Without this change, inserting an object of a subclasss with a
larger size would corrupt your memory.

Tom
 
M

Max M.

Thomas said:
Note that Max made the change from an array of CPeople to an array of
CPeople*.  Without this change, inserting an object of a subclasss with a
larger size would corrupt your memory.

Tom, this sentence doesn't make much sense. One cannot *insert* an object
into an array. Rather, one can use the assignment operator to change an
element's value. Marco's original code was perfectly legal and had well
defined behaviour, though different from what he expected.

Max
 
T

Thomas Wintschel

Max M. said:
Tom, this sentence doesn't make much sense. One cannot *insert* an object
into an array. Rather, one can use the assignment operator to change an
element's value. Marco's original code was perfectly legal and had well
defined behaviour, though different from what he expected.

Max

Apologies. I should not have used the word 'insert' and duly chastise
myself.

I was hoping to help him avoid running into any unexpected behaviour by
pointing out that instances of subclasses with additional data members could
not safely be stored in an array of base class objects, as in the following
example.

class Small
{
public:
Small() : m_n1(1) {};
Small& operator = (const Small &rhs)
{
m_n1 = rhs.m_n1;
return *this;
}
int Getn1() { return m_n1; }
void Setn1(int n) { m_n1 = n; }
private:
int m_n1;
};

// Make 'Big' twice the size of a 'Small'
class Big : public Small
{
public:
Big() : m_n2(2) {};
Big& operator = (const Big &rhs)
{
Small::eek:perator=(rhs);
m_n2 = rhs.m_n2;
return *this;
}
int Getn2() { return m_n2; }
void Setn2(int n) { m_n2 = n; }
private:
int m_n2;
};

int main()
{
Small smalls[2];

Big big;
smalls[0] = big; // Only the 'Small' part of big is copied

// Unsafe, smalls[0] contains a 'Small', not a 'Big'
Big* pBig = static_cast< Big* >(&smalls[0]);

// Returns 1, as expected
int n1 = pBig->Getn1();

// Also returns 1, since it reading the value from
// the location where smalls[1] is stored
int n2 = pBig->Getn2();

// Modifying the subclass now affects the subsequent element in the
array
pBig->Setn2(3);
// Which now contains the value 3 instead of 1
n1 = smalls[1].Getn1();

// Extra dangerous, since it goes past the end of the array
pBig = static_cast< Big* >(&smalls[1]);
// Returns 3 as the result of previous manipulations
n1 = pBig->Getn1();
// Returns ?
n2 = pBig->Getn2();
}
 
B

Bob Hairgrove

Tom, this sentence doesn't make much sense. One cannot *insert* an object
into an array. Rather, one can use the assignment operator to change an
element's value. Marco's original code was perfectly legal and had well
defined behaviour, though different from what he expected.

He was referring to slicing which, although it might not "corrupt"
memory here, will indeed cause memory leaks.
 
M

Max M.

Bob said:
He was referring to slicing which, although it might not "corrupt"
memory here, will indeed cause memory leaks.

I don't get you. In what circumstances could slicing result in a memory
leak? Are you implying the code from Marco's first post (which assigned
derived-class objects to base-class ones) causes memory leaking? It does
not, actually.

Max
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,155
Messages
2,570,871
Members
47,401
Latest member
CliffGrime

Latest Threads

Top