Assignment Operator for Class Derived from ABC

Hi,

I have a problem defining an assignment operator for a class derived from an abstract base class where memory is allocated dynamically in both the base and derived classes. I would like to be able to use a pointer to objects of type "base" to manipulate objects of type "derived". Specifically, I would like to assign the base class pointers to the addresses of derived objects, be able to de-reference the base class pointers and then use the assignment operator. Defining the assignment operator for the derived class is straightforward, but the problem is that I cannot use the default assignment operator in the base class because it uses dynamically allocated memory. I have therefore attempted to protype a virtual assignment operator for the base class without success. My attempted code is below. I understand that the in the simple example I have provided, a base class pointer is not really necessary. But I intend to have many classes derived from "base" and thereby need the base class pointer.

Thanks for your help...

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
#include <iostream>
using namespace std;

class base {
	public:
		double *a;
		base(double aParam) { a = new double; *a = aParam; };
		base() { a = new double; *a = 0; };
		~base() { delete a; }
		base(const base &baseParam) { a = new double; *a = *baseParam.a; }
		virtual void show() = 0;

		//PROBLEM HERE
//		virtual derived &operator=(const derived& derived) = 0; 
		//If I leave this line in, will not compile.
		//If I remove, the default assignment operator is called and programme hangs
};
class derived : public base {
	public:
		double *b;
		derived(double aParam, double bParam) : base(aParam) { 
			b = new double; *b = bParam; 
		}
		derived() : base() { 
			b = new double; *b = 0; }
		~derived() { 
			delete b; 
		}
		derived(const derived &derivedParam) : base(derivedParam) { 
			b = new double; *b = *derivedParam.b; 
		}
		void show() { 
			cout << *a << " " << *b << endl; 
		}
		derived &operator=(const derived& derivedParam) { 
			*a = *derivedParam.a; *b = *derivedParam.b; return *this; 
		}
};

int main(){
	base *ptrB1, *ptrB2;
	derived objD1(5,6), objD2;
	ptrB1 = &objD1;
	ptrB2 = &objD2;
	*ptrB2 = *ptrB1;
	ptrB2->show();

	return 0;
}
virtual derived &operator=(const derived& derived) = 0; //in class base The problem is if you are going to have a lot of classes derived, then you will need to overload the operator with every derived class.
1
2
3
4
5
virtual base& operator=(const base& B) = 0;//bass class
virtual base& derived::operator=(const base& B){
  const derived &D = dynamic_cast<const derived &>(B); //this could fail
  //...
}
You will need to catch a bad_cast exception if you mess up with the assignment.
Hi ne555,

Thanks for taking them time to reply. Yes, I had been mucking around with casting (admittedly only the standard cast) but was a bit worried about resorting to this. Is what I am attempting to do ill-conceived? Would it be preferable to forget about supporting the assignment operator for pointers to base classes and instead limit assignment to objects of derived type?
You don't want the assignment operator for this.

Most of the time, making the assignment operator (or really any operator) virtual is a bad idea, since it won't do what the user expects.

There must be a better way to go about this. Why do you need to reassign something polymorphic like this? I'm trying to imagine a situation where that would be useful but I can't think of one.
Hi Disch,

I use a variety of multidimensional arrays (based on C arrays, vectors and Blitz arrays) and want to write a common interface to interact with these (although one could not tell from the code snippet I posted). So my idea was to use an abstract base class containing virtual operators and a class derived from this for each array type that would hold the data and implement the operators. What I hope to do is then use base class pointers, direct them at derived objects and then call the operators by de-referencing the pointers. I guess this is more of a learning exercise than anything I actually need, but it would be good to know if this approach is badly conceived.

Thanks for taking the time to reply…
If you want to be able to reassign between types, you don't need inheritance, you can just overload the desired operator for each type:

1
2
3
4
5
6
7
8
class MyArray
{
public:
  MyArray& operator = (const MyArray& r);  // for normal arrays
  MyArray& operator = (const SomeOtherArray& r);  // for some other array
  //...
  // etc
};


Polymorphism doesn't really help you here since you would need to downcast (which pretty much negates its benefits)
Yeah, I am sort of working against the spirit of polymorphism, aren’t I? I'll forget about virtual operators for the base class and just implement them at the derived class level. Thanks again for your help...
Topic archived. No new replies allowed.