Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

problem printing array member data from a derived class

Status
Not open for further replies.

bilbobaggio

Technical User
May 17, 2005
7
GB
I am having trouble with inheritance. here is a code sample. when i run the program it displays the first B object (ie the array of integers) but then i get an access violation. can anybody let me know what i am doing wrong? when i only create a pointer to a single B object it works fine. but trying to print an array of B's gives errors.

class A {
A(/*data*/){}
~A(){}
...
virtual ostream& print(ostream& out) const
{/*add to the stream*/};
...
}

class B : public A {
B(/*data*/) : A(/*data*/)
{ data = new int[5]; /*init array also*/}
~B(){delete [] data;}
int* data;
...
virtual ostream& print(ostream& out) const
{/*add data array to the stream*/};
...
}

main()
{
A* array;
array = new B[3];
for (int i=0; i<3; i++)
array.print(cout);
}


 
Your constructors & destructors should be public, but I'm guessing you left that out of the code you posted, otherwise it wouldn't compile.
Your destructors should be virtual, otherwise you'll be leaking memory since the B destructor never gets called.
 
Actually, you cannot have a base class pointer to an array of derived class objects. The sizes won't match up and the compiler gets confused. The result is undefined behavior.

What you need is an array of pointers to A:
Code:
A* array[3];
for (int i=0; i<3; i++)
  array[i] = new B;
for (int i=0; i<3; i++)
  array[i].print(cout);
for (int i=0; i<3; i++)
  delete array[i];
Note that I used a local array instead of dynamically allocating it. If you need an array that doesn't have a constant size, you should use a vector, or you'll have to add an extra new to create the array.

With this code as well, you need to make the destructor for the base class virtual, or the result is undefined behavior which is usually just a failure to call the derived destructors.
 
thanks for the help. the above code works for constant array size. however it gives an error when trying to delete the array.

Also, I would like to have a dynamic array size. When using new it seems that the array is of type A and not A* so A::print gets called instead of B::print. Also when I use the vector i get an error when trying to print the values. My complete test code is shown here.

Code:
#include <iostream.h> 

class A {

protected: 
	int len;
public:
	A(int l=5) : len(l) {} 
	virtual ~A() { cout << "a dtor" << endl; }
	friend ostream &operator<< (ostream &out, A &a) { return a.print(out); };
	virtual ostream& print(ostream& out) const
	{ out << "A::operator<<"; return out; }

};

class B : public A {

protected:
	int* data;
public:
	B(int l=5) : A(l) { data = new int[len]; for (int i=0; i<len; i++) data[i] = i; }
	virtual ~B() 
	{ delete [] data; cout << "b dtor" << endl; }
	friend ostream &operator<< (ostream &out, B &b)
	{ return b.print(out); }
	ostream& print(ostream& out) const
	{ for (int i=0; i<len; i++) out << data[i] << " "; return out; }
};

#include <vector>
using namespace std;

void main(void)
{
	A* ptr;
	A* array[3];
	//A* array; array = new A[3];
	int i;

	for (i=0; i<3; i++)
	{
		cout << "Assinging B to A" << endl;
		ptr = new B;
		array[i] = ptr;
		//array[i] = *ptr;
	}

	for (i=0; i<3; i++)
		cout << *(array[i]) << endl;
		//cout << array[i] << endl;

	vector<A*> vec(2);

	for (i=0; i<3; i++)
	{
		ptr = new B;
		vec.push_back(ptr);
	}

	for (i=0; i<3; i++)
		cout << *(vec[i]) << endl; // gives an error

	delete ptr;

	for (i=0; i<3; i++)
		delete array[i]; // gives an error

}
 
Thanks again for the help.

I figured out how to do the dynamic array. I needed an A** arrray. here is my main code

Code:
void main(void)
{
	int size;
	cout << "Enter size of the array << ";
	cin >> size;

	A** array; array = new A*[size];
	int i;

	for (i=0; i<size; i++)
		array[i] = new B;

	for (i=0; i<size; i++)
		cout << *(array[i]) << endl;	

	for (i=0; i<size; i++)
		delete array[i]; 
}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top