Pointers Polymorphism

Hello guys! Thanks in advance for your interest. My question seems to be ridiculously long but I just want you guys to look at line 253~266. I swear to god this WAS my homework last semester but I tried hard but I didn't do well... So I am just going over all the material on my own while I am on a break as I am taking a higher class next semester. However I've been working on only this for the past 3 days but can't possibly get my code to work... and I am about to blow up inside. Could you guys please take a look at line 253~266? It was originally 9 separate files but I didn't know how to ask this kind of question on this forum. I put all the files together and it became ridiculously long... Again, This is NOT my homework... It WAS...

I am still confused about pointers and polymorphism. If you look at the lines, I do definitely not know how to use them. Because it throws an error.

Please use the other lines as a reference (There must be a lot wrong)
Your suggestions and advice will be sincerely appreciated and if you guys can get my code to work, changing it the least. I will really appreciate it... Thanks

Objective: Create an abstract class named hadron which will store the names of hadrons(meson,baryon or pentaquark) as a constant static array named HADRONARR, the size of the static array as a static constant HADRONARRSIZE, an Integer which stores the size of a hadron's quark array and qPtr that stores the quark objects that make up the hadron. It should be able to set the quarks, return individual or sets of quarks, get its name, total charge and mass and return the number of quarks in the hadron.
-mesons have 2 quarks.
-baryons have 3 quarks.
-pentaquarks have 5 quarks.

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
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
  #include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include <climits>
#include <iomanip>

static const unsigned short QUARK = 6;
static const unsigned short HADRON = 3;
static const std::string qName[QUARK] = { "Up","Down","Charm","Strange","Top","Bottom" };
static const std::string qCharge[QUARK] = { "+2/3","-1/3","+2/3","-1/3","+2/3","-1/3" };
static const std::string HADRONS[HADRON] = { "Meson","Baryon","Pentaquark" };


// I am to use this "Quark" class that contains quarks with masses, names and charges
class quark
{
public:
	quark(const double massIn = 1.5);
	~quark();
	void setMass(const double);
	std::string getName()const;
	std::string getCharge()const;
	double getMass()const;
protected:
	double mass;
	unsigned short index;
};
quark::quark(const double massIn)
{
	setMass(massIn);
}
quark::~quark()
{
}
void quark::setMass(const double massIn)
{
	if (1.5 <= massIn&&massIn <= 3.3)
		index = 0;
	else if (3.5 <= massIn&&massIn <= 6.0)
		index = 1;
	else if (1160.0 <= massIn&&massIn <= 1340.0)
		index = 2;
	else if (70.0 <= massIn&&massIn <= 130.0)
		index = 3;
	else if (169100.0 <= massIn&&massIn <= 173000.0)
		index = 4;
	else if (4130.0 <= massIn&&massIn <= 4370.0)
		index = 5;
	mass = massIn;
}
std::string quark::getName()const
{
	return qName[index];
}
std::string quark::getCharge()const
{
	return qCharge[index];
}
double quark::getMass()const
{
	return mass;
}

//Abstract base class
class hadron
{
public:
	hadron(const std::string hIn = "Meson");
	virtual~hadron() = 0;
	std::string getHadName()const;
	virtual unsigned short getSize()const = 0;
	quark* get()const;
	virtual std::string getCharge()const = 0;
	virtual double getMass()const = 0;
protected:
	unsigned short index;
	quark* qPtr;
};
hadron::hadron(const std::string hIn)
{
	for (unsigned short i = 0; i < HADRON; ++i)
	{
		if (HADRONS[i] == hIn)
		{
			index = i;
		}
	}
}
hadron::~hadron()
{
	delete[]qPtr;
}
std::string hadron::getHadName()const
{
	return HADRONS[index];
}
std::string hadron::getCharge()const
{
	return HADRONS[index];
}
double hadron::getMass()const
{
	return 0.0;
}
unsigned short hadron::getSize()const
{
	return 0;
}
quark* hadron::get()const
{
	return qPtr;
}

// sub-class inheriting hadron
class meson : public hadron
{
public:
	meson(const quark[]);
	virtual~meson();
	virtual unsigned short getSize()const;
	virtual std::string getCharge()const;
	virtual double getMass()const;
	virtual std::string getName()const;
protected:
	unsigned short SIZE;
};
meson::meson(const quark qIn[]) : hadron("Meson"), SIZE(2)
{
	qPtr = NULL;
	qPtr = new quark[SIZE];
	std::copy(qIn, qIn + SIZE, qPtr);
}
meson::~meson()
{
	delete[] qPtr;
}
std::string meson::getName()const
{
	return qPtr->getName();
}
std::string meson::getCharge()const
{
	return qPtr->getCharge();
}
double meson::getMass()const
{
	return qPtr->getMass();
}
unsigned short meson::getSize()const
{
	return SIZE;
}

// sub-class inherting hadron
class baryon : public hadron
{
public:
	baryon(const quark[]);
	virtual~baryon();
	virtual unsigned short getSize()const;
	virtual std::string getName()const;
	virtual std::string getCharge()const;
	virtual double getMass()const;
protected:
	unsigned short SIZE;
};
baryon::baryon(const quark qIn[]) : hadron("Baryon"), SIZE(3)
{
	qPtr = NULL;
	qPtr = new quark[SIZE];
	std::copy(qIn, qIn + SIZE, qPtr);
}
baryon::~baryon()
{
	delete[] qPtr;
}
std::string baryon::getName()const
{
	return qPtr->getName();
}
std::string baryon::getCharge()const
{
	return qPtr->getCharge();
}
double baryon::getMass()const
{
	return qPtr->getMass();
}
unsigned short baryon::getSize()const
{
	return SIZE;
}

//sub-class inherting hadron
class pentaquark : public hadron
{
public:
	pentaquark(const quark[]);
	virtual~pentaquark();
	virtual unsigned short getSize()const;
	virtual std::string getName()const;
	virtual std::string getCharge()const;
	virtual double getMass()const;
protected:
	unsigned short SIZE;
};
pentaquark::pentaquark(const quark qIn[]) :hadron("Pentaquark"), SIZE(5)
{
	qPtr = NULL;
	qPtr = new quark[SIZE];
	std::copy(qIn, qIn + SIZE, qPtr);
}
pentaquark::~pentaquark()
{
	delete[] qPtr;
}
std::string pentaquark::getName()const
{
	return qPtr->getName();
}
std::string pentaquark::getCharge()const
{
	return qPtr->getCharge();
}
double pentaquark::getMass()const
{
	return qPtr->getMass();
}
unsigned short pentaquark::getSize()const
{
	return SIZE;
}

void load(quark[], const unsigned short);
bool massValTest(const double);
void display(quark[], const unsigned short);

// Main
int main(void)
{

	const unsigned short qSize = 5;
	quark qArr[qSize];
	srand((unsigned)time(NULL));
	load(qArr, qSize);
	display(qArr, qSize);
	std::cout << std::endl;
	std::cout << std::endl;
	
	
	// My Problem begins... It thorws an error
	hadron** hadArr = new hadron*[3];
	hadArr[0] = new meson(qArr);
	hadArr[1] = new baryon(qArr);
	hadArr[2] = new pentaquark(qArr);

	for (unsigned short i = 0; i < 3; ++i)
	{
		std::cout << hadArr[i]->getHadName() << std::endl;
		for (unsigned short c = 0; c < hadArr[i]->getSize(); ++c)
		{
			std::cout << hadArr[i][c].getMass() << "  " << hadArr[i][c].getCharge() << std::endl;
		}
		std::cout << std::endl;
	}

	return 0;
}
bool massValTest(const double massIn)
{
	return ((1.5 <= massIn&&massIn <= 3.3) || (3.5 <= massIn&&massIn <= 6.0)
		|| (70.0 <= massIn&&massIn <= 130.0) || (1160.0 <= massIn&&massIn <= 1340.0)
		|| (4130.0 <= massIn&&massIn <= 4370.0) || (169100.0 <= massIn&&massIn <= 173000.0));
}
void load(quark qArr[], const unsigned short SIZE)
{
	double randNum;
	for (unsigned short i = 0; i < SIZE; ++i)
	{
		do
		{
			randNum = ((rand() % INT_MAX + 1) / 10.0);
		} while (!(massValTest(randNum)));
		qArr[i] = randNum;
	}
}
void display(quark qArr[], const unsigned short SIZE)
{
	std::cout << std::fixed << std::setprecision(2);
	std::cout << "\tName       Mass       Charge" << std::endl;
	for (unsigned short c = 0; c < SIZE; ++c)
	{
		std::cout << "\t" << c + 1 << ":" << qArr[c].getName() << "    "
			<< qArr[c].getMass() << "    " << qArr[c].getCharge() << std::endl;
	}
}


Last edited on
// My Problem begins... It thorws an error

What error? Exactly.

(Another environment compiles and executes your posted code fine.)
Thanks for your interest! If you were to run the code on compilers like Visual Sudio, it throws an error...In my opinion, Im not outputting properly the data stored in qPtr. I am so lost...

I'd like to output like this...

Meson
Mass Name Charge
1.101 Strange -1/3
2.99 Strange -1/3
Baryon
Mass Name Charge
1.4323 Bottom -1/3
2.1170 Charm +2/3
3.5 Down -1/3
Pentaquark
Mass Name Charge
1.101 Strange -1/3
2.99 Strange -1/3
3.4323 Bottom -1/3
4.1170 Charm +2/3
5.5 Down -1/3

Thank YOU VERY VERY MUCH
Last edited on
This code inside main():
1
2
hadron** hadArr = new hadron*[3];
hadArr[0] = new meson(qArr);

creates a single ‘meson’ which holds a pointer to quarks, whereas this code:
1
2
3
4
5
6
7
8
9
for (unsigned short i = 0; i < 3; ++i)
{
    std::cout << hadArr[i]->getHadName() << std::endl;
    for (unsigned short c = 0; c < hadArr[i]->getSize(); ++c)
    {
        std::cout << hadArr[i][c].getMass() << "  " << hadArr[i][c].getCharge() << std::endl;
    }
    std::cout << std::endl;
}

assumes more than 1 meson has been created.

You can’t access your pointers to ‘quark’ inside your classes from main() this way.
The best way would be to add functions inside your classes to manage printing the data, but a simple, dirty workaround could be to add simply a function like this
1
2
3
4
5
6
7
8
9
10
class hadron {
public:
    hadron(const std::string hIn = "Meson");
    . . .
    quark* getBunchOfQuarks() const
    {
        return qPtr;
    }
protected:
    . . .

inside your hadron class and then modify the above code this way:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    // My Problem begins... It thorws an error
    hadron** hadArr = new hadron*[3];
    hadArr[0] = new meson(qArr);
    hadArr[1] = new baryon(qArr);
    hadArr[2] = new pentaquark(qArr);

    for (unsigned short i = 0; i < 3; ++i)
    {
        std::cout << hadArr[i]->getHadName() << std::endl;
        int arsize = hadArr[i]->getSize();
        quark* myq = hadArr[i]->getBunchOfQuarks();
        for (int c = 0; c < arsize; ++c)
        {
            std::cout << "Mass: " << myq[c].getMass() 
                      << " - Charge: " << myq[c].getCharge() << '\n';
        }
        std::cout << std::endl;
    }


Output:
        Name       Mass       Charge
        1:Charm    1184.30    +2/3
        2:Strange    101.10    -1/3
        3:Charm    1302.40    +2/3
        4:Charm    1301.30    +2/3
        5:Strange    111.00    -1/3


Meson
Mass: 1184.30 - Charge: +2/3
Mass: 101.10 - Charge: -1/3

Baryon
Mass: 1184.30 - Charge: +2/3
Mass: 101.10 - Charge: -1/3
Mass: 1302.40 - Charge: +2/3

Pentaquark
Mass: 1184.30 - Charge: +2/3
Mass: 101.10 - Charge: -1/3
Mass: 1302.40 - Charge: +2/3
Mass: 1301.30 - Charge: +2/3
Mass: 111.00 - Charge: -1/3


It seems your teacher has the polymorphism bug, doesnt’ it?
Oh my god, I never thought that it was possible with a slight change like this.
I thought I had tried every way possible :(..
Thank you SOOO much! I've learned something today and it reminds me I still have a long long way to go ... Thank you.! this part(pointers and polymorphism) is where this class got so hard so I am trying to use them as much as I can for practice. Thank you again~!

This is additional... If you don't mind, could you give me a little direction in English to add functions inside my classes to manage printing the data. (You don't have to show me the code at ALL)
I'd like to try it for practice as it would be the best way in this case.
Last edited on
@hyeon

Some ideas about the code:

Try to avoid having global variables. One idea is to collect them all into their own namespace.

It seems you are using new purely to obtain a pointer. Instead, use a std::vector, it does it's own memory management, puts it's data on the heap and makes things easier all round.

Use nullptr instead of NULL. nullptr was invented to get around the problems of using 0 as a pointer.


You have duplicated code, I agree with Enoizat the classes and their member functions look to be all the same, they only differ in their names. Why is there a need to have any derived classes at all?

Putting that idea another way:

-mesons have 2 quarks.
-baryons have 3 quarks.
-pentaquarks have 5 quarks.


mesons, baryons, and pentaquarks only differ in the number of quarks they have.

Another thing, it's not a good idea to have protected member data, it's just as bad as public data. It's better to have private data, then functions to manipulate it, though don't fall into the trap of blindly writing get / set functions for each member variable.

If you are going to redefine functions in a derived classes, consider using the override keyword.

It is still worthwhile at this late stage, to see the full text of the assignment verbatim, then we can decide whether you have taken the correct approach, or the whole intent of the assignment is flawed.

Pedantically, there is no need for void here:

int main(void)

It has never been a requirement in C++ to specify void when there are no function parameters. It is more a left over from the C language.
a little direction in English to add functions inside my classes to manage printing the data. (You don't have to show me the code at ALL)

In addition to TheIdeasMan’s thorough analysis, in my poor English, my (beginner) suggestion is to overload operator<< as a friend function of class hadron.
The prototype of this overloading is canonical, so if you don’t know how to start, you can easily find it on Internet, but perhaps you’ll need to adjust its arguments to pointers instead of references. You only need to remember you want to output *all* the data pointed to by qPtr.

If I may add a (unsolicited) recommendation based on my (limited) experience, when you’re just studying new feature, you’d better focus on them rather then writing a lot of code. Now, for example, if I were you I’d start from an empty project and jot down the simplest base class possible, with just and int and a pointer to int properties, everything public.
Then Id’ write the code in main() to fill it with data and check it.
Then I’d add the friend overloaded operator<< and I’d check it.
Later, I’d add a derived class and test the overloaded operator to see if it works in a polymorphic situation.
When everything performs fine, I’ll adapt it to fit in with my ‘real’ code.

Happy coding!
Enoizat,TheIdeasMan Wow this is such a piece of advice.! I can't thank you all guys enough...
I really appreciate it from the bottom of my heart! :) Now I have a little idea of what I need to work on and how. A great big thanks to you guys! Happy coding~
Topic archived. No new replies allowed.