virtual functions?

Hi everyone,

My problem is that I am trying to use a copy constructor and an assignment constructor on an abstract class.

these are required as an assignment.

Is the above Possible? // I cant, I am getting errors?

My understanding is that once a class is abstract then we can't create an object of that class, but yet I have to have a copy constructor and an assigmnet constructor!!!

Please take a look at my code and see what I can change if the upper comments are possible...

I have commented out the assignment constructor, it gives me error.
Thanks in advance.

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
#include <iostream>
#include <string>
#include <cctype>
#include <conio.h>

using namespace std;
const int MAX = 20;
class Pet
{
private:
	char* name;
	int age;
	double weight;
public:
	Pet(){ name = 0; age = 0; weight = 0.0;}// default constructor
	Pet(const char*, int, double); // argument constructor
	Pet(const Pet& otherPet);
	~Pet();
	//Pet& operator = (Pet otherPet);
	double getWeight()const{return weight;} // Accessor
	void getInfo() const;// Accessor
	void setInfo(); // pure virtual function
	virtual void getLifespan()=0;// pure virtual function
};
///////////////////////////////////////////////////////////////////////////////
// Class Pet declerations
Pet::Pet(const char* n, int a, double w)
{
	size_t length = strlen(n)+1;
	name = new char[length];
	strcpy_s(name, length, n);

	age = a;
	weight = w;
	
}

// Here I can't assign another object, Pet is abstract??!!!
Pet::Pet(const Pet& otherPet)
{
	if (otherPet.age == 0)
	{
		cout << "About to deref null pointer" << endl;
		exit(1);
	}
	size_t length = strlen( otherPet.name )+1;
	name = new char[strlen(otherPet.name)+1];
	strcpy_s(name, length, otherPet.name);		

	age = otherPet.age;
	weight = otherPet.weight;
}
Pet::~Pet()
{
	delete[] name;
}

// This is comented becasue it gives me error.
//Pet Pet::operator =(Pet otherPet)
//{
//	delete[]name;
//
//	int length = strlen(otherPet.name)+1;
//	name = new char[length];
//	strcpy_s(name, length, otherPet.name);
//
//	age = otherPet.age;
//	weight = otherPet.weight;
//
//	return *this;	
//}

void Pet::setInfo()
{
	char ch[20] = "";
	int a;
	double w;

	cout <<"Enter the name: " ; cin >> ch;
	
	delete[] name;
	int length = strlen(ch)+1;
	name = new char[length];
	strcpy_s(name, length, ch);

	cout <<"Enter the age: "; cin >> a;
	age = a;
	cout <<"Enter the weight: "; cin >> w;
	weight = w;
}
void Pet::getInfo() const
{
	if (name != NULL)
	{
		cout <<"Pet Name:   " << name << endl;
		cout <<"Pet Age:    " << age << endl;
		cout <<"Pet Weight: " << weight << endl;
	}
	else if (name == NULL)
	{
		cout <<"Pet Name:    N/A" << endl;
		cout <<"Pet Age:    " << age << endl;
		cout <<"Pet Weight: " << weight << endl;
	}

}
void Pet::getLifespan()
{
	string s = "Uknown lifesapn ";
	cout << s << endl;
}
// Class Dog derived from Pet
class Dog : public Pet
{
private:
	string breed;
public:
	Dog(): Pet(), breed(" "){}
	Dog(char* n, int a, double w, string b):Pet(n, a, w), breed(b){}
	void setBreed();
	void getInfo()const;
	virtual void getLifespan();
};
///////////////////////////////////////////////////////////////////////////////
// Class Dog derived from Pet declerations
void Dog::setBreed()
{
	string b;

	cout <<"Enter the breed: "; cin >> b;
	breed = b;
}
void Dog::getInfo() const
{
	Pet::getInfo();
	cout <<"Pet breed: " << breed << endl;
}
void Dog::getLifespan()
{
	string s1, s2;
	double w;

	s1 = "The lifespan is under 7 years.";
	s2 = "The lifespan is 13 years.";
	
	w = Pet::getWeight();
	
	if (w > 100)
	{
		cout << s1 << endl;
	}
	else if (w < 100)
	
		cout << s2 << endl;
	else if (w == 100)
	{
		Pet::getLifespan();
	}
}

// Clas Rock derived from Pet
class Rock : public Pet
{
public:
	Rock(): Pet(){}
	Rock(char *n, int a, double w): Pet(n, a, w){}
	virtual void getLifespan();
};

void Rock::getLifespan()
{
	string s = "Thousand  of years";

	cout << s << endl;	
}

int main()
{
	Pet *p1[20];
	int i = 0;
	char choice;

	// Pet p2; p3("k-9", 5, 60.5, "german shepard");
         // p2(p3);  // I cant do this
         // p2 = p3; // I cant do this
	do 
	{
		cout <<"Enter (d) for Dog or (r) for Rock: ";
		cin >> choice;
         	cout << endl;

		toupper(choice);

		if (choice == 'D'|| choice == 'd')
		{
			p1[i] = new Dog;;
		}
		else if (choice == 'R'|| choice == 'r')
		{
			p1[i] = new Rock;
		}
		p1[i++] ->setInfo();

		cout <<"Enter again (y/n): ";
		cin >> choice;
		cout << endl;
	}while (choice == 'Y' ||choice == 'y');
	
	for (int j = 0; j<i; j++)
	{
		p1[j] ->getLifespan();
		cout << endl;
		delete p1[j];
	}
	return 0;
}
Last edited on
You can have constructors and copy-ctors, you just can't actually use them unless the class is not abstract.
Then how do you explain the error I get on the assignment constructor?

If I uncoment that out the program will not compile,

Am I doing something wrong on the declearation?
Pet Pet::operator =(Pet otherPet)

Here you are trying to make an instance of pet (otherPet), which is an error because Pet is abstract.
The correct signature of the assignment operator would be

Pet& operator=(const Pet& otherPet);

Give that a go and see what happens.
can I change this so I do not have to comment it out,

or having an assignment constructor will not work at all?
Change it to what jim80y suggested.
Thanks a lot everyone.
That did work.

Can someone explain what is happing though please:
Pet& operator=(const Pet& otherPet);
If you define the parameter as Pet otherPet, that's an actual instance of a Pet object (passed by value) and will require copy constructing during the call - which you can't do, as Pet is abstract.

By using Pet& otherPet, you're saying it's a reference to a Pet object that's been constructed elsewhere, so there's no copying going on.

Also, keep in mind that via polymorphism a Pet reference can refer to a Pet and any instance of a class derived from Pet, which includes Rock. So the Pet assignment operator will successfully be used to assign Rocks.

The const qualifier just says you promise not to modify the other Pet while you're copying its values.
Just to nit-pick, it's the [copy] assignment operator, not constructor.
thanks jim80y.
No worries
Topic archived. No new replies allowed.