Custom object constructor is looping outside of a loop - c++

For some reason when I create an object of Student in my code the constructor is entered many many times and I am not sure why. I put a cout statement in the constructor and the code below. Any help of why this is happening would be great.
//Student.cpp
Student::Student() {
ID = 0;
name = "name";
cout << "student constructor" << endl;
}
Student::Student(int id, string name) {
ID = id;
name = this->name;
cout << "student con 2" << endl;
}
//part of SortedList.cpp just incase it is needed
template <class ItemType>
SortedList<ItemType>::SortedList() {
cout << "In the default constructor" << endl;
Max_Items = 50;
info = new ItemType[Max_Items];
length = 0;
//SortedList(50);//Using a default value of 50 if no value is specified
}
//Constructor with a parameter given
template <class ItemType>
SortedList<ItemType>::SortedList(int n) {
cout << "in the non default constructor" << endl;
Max_Items = n;
info = new ItemType[Max_Items];
length = 0;
cout << "At the end of the non default constructor" << endl;
}
/The part of the driver where this is called
ifstream inFile;
ofstream outFile;
int ID; //what /below
string name; //these werent here
inFile.open("studcommands.txt");
outFile.open("outFile.txt");
cout << "Before reading commands" << endl;
inFile >> command; // read commands from a text file
cout << "After reading a command" << endl;
SortedList<Student> list;//() was-is here
cout << "List has been made" << endl;
Student StudentObj;
cout << "Starting while loop" << endl;
while(command != "Quit") {...}
//I am also getting a segmentation fault core dump a little after.
UPDATE For some reason however long I make my list, my student constructor is entered that many times meaning say I enter 30 as the length in my list the constructor is entered 30x instead of just creating an array with 30 slots. What could be the reason with this? I feel as If I have heard of this issue in the past.

In the SortedList constructor, you create a new array of the input size of ItemType objects. The elements of this array will be default constructed when the array is being built. That is why your Student constructor is being called size of the array times.

Related

No Names returned in search function

So I cant get my search function to return to the actual title of the movies with the instantiated array with a movie title, director, and actor. I create an array of objects, instantiate it, run a do while loop to get the position, and run a search algorithm to get the title, director, and actor of the movie. But for the life of me I cant get the code to return the actual title, director or actor. It will say the name is in the list, but returns an empty space. I linked a picture below to show the return. When I add a movie to the array it says the movie does not exist in the array.
The movie Class:
class Movies{
private:
// variables
string titleCode;
string directorCode;
string actorCode;
public:
// constructors
Movies() // default constructor, allows no arguments.
{
//titleCode = "Home Movie"; directorCode = "Colin Powers"; actorCode = "Colin Powers";
}
Movies(string t, string d, string a) // constructor
{
titleCode = t; directorCode = d; actorCode = a;
}
// getter
string getTitle() const
{
string title = titleCode;
return title;
}
string getDirector() const
{
string director = directorCode;
return director;
}
string getActors() const
{
string actors = actorCode;
return actors;
}
// setters
void setTitle(string t) // cout/cin were giving random "ambigious" error so i added std:: till they all stopped giving it.
{
std::cout << "Enter the title of the Movie: " << endl;
std::cin >> t;
titleCode = t;
}
void setDirector(string d)
{
std::cout << "Enter the Director of the Movie: " << endl;
std::cin >> d;
directorCode = d;
}
void setActors(string a)
{
std::cout << "Enter the main protagonist: " << endl;
std::cin >> a;
actorCode = a;
}};
Movies Array:
Movies moviesArr[ARR_SIZE];
Function prototype for the search function
int searchMovies(const Movies[], int, string);
Instantiated array of objects to search through
Movies hollywood[ARR_SIZE] =
{ // title, director, actor
Movies("Avatar", "James", "James"),
Movies("Terminator", "John", "John"),
Movies("Predator", "Michael", "Michael")
};
Do while to get returned position and names:
do
{
// get the movie title
cout << "Enter the movie title to search: " << endl;
cin >> title;
// search for the object
pos = searchMovies(hollywood, ARR_SIZE, title);
// if pos = -1 the title was not found
if (pos == -1)
cout << "That title does not exit in the list.\n";
else
{
// the object was found so use the get pos to get the description
cout << "The movie: " << moviesArr[pos].getTitle() << " is in the list. " << endl;
cout << "It was Directed by: " << moviesArr[pos].getDirector() << endl;
cout << "It also stars: " << moviesArr[pos].getActors() << endl;
}
// does the user want to look up another movie?
cout << "\nLook up another movie? (Y/N) ";
cin >> doAgain;
} while (doAgain == 'Y' || doAgain == 'y');
Search function to search array:
int searchMovies(const Movies object[], int ARR_SIZE, string value){
int index = 0;
int position = -1;
bool found = false;
while (index < ARR_SIZE && !found)
{
if (object[index].getTitle() == value) // if the title is found
{
found = true; // set the flag.
position = index; // record the values subscript
}
index++; // go to the next element.
}
return position; // return the position or -1;}
output looks like:
Nondescrip return, no names, no director, no title.
This line:
Movies moviesArr[ARR_SIZE];
defines an empty, uninitialized array of Movies. You are searching for a particular Movie title in hollywood, which finds the movie. However, you are then indexing moviesArr:
cout << "The movie: " << moviesArr[pos].getTitle() << " is in the list. " << endl;
which is undefined behaviour (and printed nothing for the title in your case).
Replace that with:
cout << "The movie: " << hollywood[pos].getTitle() << " is in the list. " << endl;

Enlarge a dynamic array (no vector<> allowed, class assignment)

This is my first problem to ask about, please scrutinize me if necessary :)
I'm trying to solve a problem for a C++ class at school. I have encountered an error I really can't grasp. I'm in taking my baby steps in programming.
The assignment says:
two classes,
inheritance mechanism used,
database holding students using dynamic memory allocation,
a way of enlarging the database without using advanced data structures,
overload stream operators for objects of created class.
This is my code:
#include <conio.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
class Person
{
protected:
char Name[20];
string Surname;
int Age;
public:
virtual void whoAmI()=0;
friend ostream &operator<< (ostream &out_, Person &s); // stream overl.
friend istream &operator>> (istream &in_, Person &s);
friend void resizeArr(Person* oldList, int oldSize, int newSize); // array enlarge
};
class Student :public Person
{
public:
Student(){}
Student(char name[], string surname, int age )
{
strcpy(Name, name);
Surname = surname;
Age = age;
}
virtual void whoAmI() // basically replaced by overloaded ostream
{
//cout << "I am a student\nMy name is " << name <<" "<< surname << "; I'm "<< age << " years old.";
cout << Name << endl;
cout << Surname << endl;
cout << Age << endl;
}
};
istream &operator>> (istream &in_, Person &s) // through reference: stream object and overloading object
{
cout << "New student record: "<< endl;
cout << "Name: " << endl;
in_ >> s.Name;
cout << "Surname: " << endl;
in_ >> s.Surname;
cout << "Age: " << endl;
in_ >> s.Age;
cout << endl;
return in_;
}
ostream &operator<< (ostream &out_, Person &s)
{
out_ << "Name:\t\t" << s.Name << endl << "Surname:\t" << s.Surname << endl <<"Age:\t\t" << s.Age << endl;
return out_;
}
void resizeArr(Student* oldList, int oldSize, int newSize)
{
Student *newList = new Student[newSize];
for(int i = 0; i < oldSize; i++) // COPYING
{
newList[i]=oldList[i];
}
for(int i = oldSize ; i < newSize ; i++) // init rest as blank students to avoid errors
{
newList[i] = Student( "undef" , "undef", 0);
}
delete [] oldList; // free memory used for old array
oldList = newList; // reset pointer to new array
}
int main()
{
int initSize = 2;
int plusSize = 4;
Student *list1 = new Student[initSize];
for (int i=0; i<initSize; i++){ // initialize each cell as a blank student
list1[i] = Student( "undef" , "undef", 0);
}
for (int i=0; i<initSize; i++) // display initial array
{
cout << list1[i] << endl << "------------------------------" << endl; // for the sake of console output clarity
}
resizeArr(list1, initSize, plusSize); // FUNCTION CALL
cout << endl << "\tEnlarger database: " << endl << endl; // for the sake of console output clarity
for (int i=0; i<plusSize; i++) // display enlarged array
{
cout << list1[i] << endl << "------------------------------" << endl; // for the sake of console output clarity
}
getch();
return 0;
}
I have previously prototyped such a mechanism using integer arrays and it worked... now I'm getting a crash for an unknown reason.
Please point me in the right direction.
Edit:
The program compiles and runs, the new array seems to hold the first two elements of the old array, and by the point it reaches the first new element, the program crashes (the memory cell seems to be trolling me and holds a smiley face).
The first two Student objects are copied, the third element causes an error:
The issue lies in the definition of your resize function:
void resizeArr(Student* oldList, int oldSize, int newSize)
Unless otherwise noted, all parameters passed to a function are by value. Even though the first parameter is a pointer, that only allows to modify the memory to which it is pointing, not the pointer itself.
You need to change the declaration of the first parameter to either Student **, with code changed in the method to handle the double dereference, or change it to Student*&.
I suspect that you were lucky that it worked for integer.
You are passing a pointer to a student list to your resizeArr routine, i.e. void resizeArr(Student* oldList, int oldSize, int newSize), but not a pointer to a pointer.
Hence, assigning a new/different memory block to the pointer within resizeArr will let the variable within resizeArr point to the new address, but the pointer that has been passed to resizeArr (i.e list1) is not changed.
I'd suggest to change the logic to Student* resizeArr(Student* oldList, int oldSize, int newSize) and call it like list1 = resizeArr(list1, initSize, plusSize);
This is analogous to the signature of void* realloc (void* ptr, size_t size);.

C++ OOP Classes and Constructors

Pretty new to C++ here and programming as a whole so please be patient and understanding that my explanations may not be on the mark. The assignment for my OOP class calls for the following:
Design an Inventory class that can hold information for an item in a retail store's inventory.
Required private member variables:
- item number
- quantity
- cost
Required public member functions
Default constructor - Sets all the member variables to 0
Constructor #2 - Accepts an item's number, quantity and cost as arguments. Calls other class functions to copy these values into the appropriate member variables.
They way I'm going about this is slightly different. Rather than 1 value I'm trying to initialize an array and store all the values enter by the user there. However it seems, once the user exits the member/class function the value is removed from the array.
Kind of at my wits end here so any info or recommendations would greatly help.
#include <iostream>
using namespace std;
class inventory
{
private:
int productNum[10];
int productCount[10];
double productPrice[10];
int inventoryFillLevel;
int userPNumber;
int userQuantity;
double userPrice;
public:
inventory()
{
int counter = 0;
userPNumber = 0;
userQuantity = 0;
userPrice = 0;
while (counter < 10)
{
productNum[counter] = 5;
productCount[counter] = 6;
productPrice[counter] = 7;
counter++;
}
}
inventory(int pNumber, int pCount, int pPrice)
{
cout << "Now we're in the 2nd constructor in the Class" << endl;
cout << "The 1st number entered by the user is: " << pNumber << endl;
cout << "The 2nd number entered by the user is: " << pCount << endl;
cout << "The 3rd number entered by the user is: " << pPrice << endl;
Input(pNumber);
}
void Input(int pNumber)
{
int counter = 0;
cout << "\nNow we're in the function as called by the Constructor." << endl;
cout << "The 1st number entered by the user is: " << pNumber << endl;
cout << "In the function the counter is: " << counter << endl;
cout << "The value in the array at " << counter << " is: " << productNum[counter] << endl;
cout << "Now we set that to the value entered by the user" << endl;
productNum[counter] = pNumber;
cout << "And now the value in the array is: " << productNum[counter] << endl;
}
void Show()
{
int counter = 0;
cout << "After entering the value, let's check what is stored in the array: ";
cout << productNum[counter] << endl;
}
};
int main()
{
int a=0;
int b=0;
int c=0;
inventory inv1;
cout << "1st User entered value" << endl;
cin >> a;
cout << "2nd User entered value" << endl;
cin >> b;
cout << "3rd User entered value" << endl;
cin >> c;
cout << "Now we call the 2nd constructor and pass the values to it" << endl;
inventory(a, b, c);
inv1.Show();
return 0;
}
Thanks again for any help with this.
You appear to be handling your class incorrectly. The line
inventory(a, b, c);
only creates a temporary instance of inventory that is gone essentially after the line finishes execution. So when you call inv1.Show() it's still using the values that are assigned in your default constructor when inv1 was declared. You should remove the current declaration of inv and change
inventory(a, b, c);
to
inventory inv1(a, b, c);
Value are not getting removed. There is small flaw in the code.
1)- You are making mistake while creating an object. You are calling Show method with object created by default constructor.
inventory inv1;
....
inv1.Show();
Change the declaration of inv1 to inventory inv1(a, b, c); and call then call show method.
Also inventory(a, b, c); will create new object and will not effect inv1.
2)- You are always storing values at index 0 of the member array.
As you are declaring int counter = 0 whenever you are calling any method/constructor.
Make int counter ; a class member.
class inventory
{
private:
int counter;
public:
inventory():counter(0){....}
....
};
It will count the items you already push in your inventory.
Though you will have to take care how many item you already pushed in.
Alternative approach can be you can use std::vector instead of int array .

arry of pointers ( classes )

So I have these classes:
In main I wrote an array of pointers:
student *arry[10];
How can I make each cell point to an object of a different class?
For example :
I want the cell 0 , 2 , 4
point to an object of class medstudent
using ( new statement )
thank you
here is class medStudent
#include<iostream>
#include"student.cpp"
using namespace std;
class medStudent:public student {
public :int clinicH;
public:
medStudent(int ch, string n , int i ):student(n,i){
setClinicH(ch);
cout << "New Medecine Student" << endl;
}
~medStudent(){
cout << "Medecine Student Deleted" << endl;
}
medStudent(medStudent & ms):student(ms){
cout << "New Copy Medecined Student" << endl;
}
medstudent(){
}
void setClinicH(int ch){
clinicH = ch;
}
int getClinicH()const{
return clinicH;
}
void print()const{
student::print();
cout << "Clinical Hours: " << getClinicH() << endl;
}
};
Here is class student:
#include <iostream>
//#include"medstudent.cpp"
using namespace std;
class student//:public medstudent
{
public :
static int numberOfSaeeds;
const int id;
string name;
public:
~student(){
cout << "Delete Student: " << getName() << " " << endl ;
}
student(string n, int i):id(i){
setName(n);
cout << "Student with args" << endl ;
}
void setName(string n){
name = n;
}
string getName()const{
return name;
}
void print()const{
cout << "My name is: " << name << endl;
cout << "My ID is: " << id << endl;
}
void setNOS(int nos){
numberOfSaeeds = nos;
}
int getNOS(){
return numberOfSaeeds;
}
void printAddress()const{
cout << "My address is " << this << endl;
}
student * getAddress(){
return this;
}
student(student & sc):id(sc.id){
name = sc.name;
setName(sc.getName());
cout << "New Object using the copy constructor" << endl;
}
};
Here is main code:
#include<iostream>
using namespace std;
#include"time.cpp"
#include "student.cpp"
//#include"medstudent.cpp"
int main(){
student a1("asa" , 2);
student * a[10];
a[3]= new student("jj", 22 );
a[0] = new medStudent();
}
Since you explicitly declare a medStudent constructor the compiler will not create a default constructor for your class. And when you do new medStudent(); you are (explicitly) trying to invoke the default constructor, which doesn't exist.
That will give you a build error, one that should have been very easy to diagnose if you read it and most importantly shown it to us (when asking questions about build errors, always include the complete and unedited error output, including any informational output, in the body of the question, together with the code causing the error).
The solution? Call the existing parameterized constructor. E.g. new medStudent("foo", 123).
By the way, if you want inheritance to work okay, and the base-class destructor to be called when deleting an object of a child-class, then you need to make the destructors virtual.

How to create a function in another file with objects and call it from main

I want to be able to make a battle scene and put it into a function, but every time i try i have to create objects in a different header file, which i then cant call in main. To try to fix this i made the loop in the main function but it says the object calling the method must be modifiable.
//main.cpp
int main()
{
Characters h;//Created using normal constructor
cout << "Character: \n";
h.setAttack(5);
h.getAttack();
h.setDefense(15);
h.getDefense();
Hero Me;
cout << "Hero: \n";
Me.setAttack(10);
Me.getAttack();
Me.setHp(5);
Me.getHp();
Hero::Hero(1,2,3,4);//Created using overloaded constructor
Monsters m;
cout << "Monster: \n";
m.setAttack(20);
m.getAttack();
Monsters::Monsters(5,6,7,8);
//Problem is this this loop! i cant access the member functions for my objects.
//And i want to be able to put this in a function and call it from another file!
do
{
cout << "Attacking!\n";
cout << "Your hp is: " << Me.getHp() << endl;
cout << "The enemy's hp is: "<< m.getHp << endl;
cout << "\nThe monster has attacked you!\n";
cout << "You received " << m.getStrength() << " damage;" << endl;
Me.setHp() -= m.getStrength() ;//It compiles an error, saying its not modifiable
cout << "\nYour hp is now: " << Me.getHp() << endl;
cout << "Enemy hp is: "<< m.getHp << endl;
cout << "\nNow you attacked!\nYou have dealt "<< Me.getAttack() << " Damage" << endl;
m.setHp() -= Me.getAttack();
cout << "Enemy hp is now: " << m.getHp() - Me.getAttack() << endl;
}while ((Me.getHp() >= 0) && (m.getHp() >= 0));
if ((Me.getHp > 0) && (m.getHp < 0))
cout <<"Congratulations! You killed the enemy!" << endl;
else if ((Me.getHp < 0) && (m.getHp > 0))
cout << "You have died!" << endl;
cin.sync();
cin.get();
return 0;
}
//Here's the rest of my code.
//Hero.h
class Hero:
public Characters
{
public:
Hero();
Hero(int, int, int, int);
~Hero(void);
};
//Hero.cpp
int Herolevel;
int HeroHp;
int HeroStrength;
int HeroAttack;
int HeroDefense;
Hero::Hero()
{
cout << "HOLA! Hero Created using normal constructor\n";
}
Hero::Hero(int newHp, int newLevel, int newAttack, int newDef)
{
cout << "Hero created using Overloaded function!\n";
HeroHp = newHp;
cout << "Hp is: "<< HeroHp << endl;
Herolevel = newLevel;
cout << "level is: " << Herolevel << endl;
HeroAttack = newAttack;
cout << "Attack is: " << HeroAttack << endl;
HeroDefense = newDef;
cout << "Defense is: " << HeroDefense << endl;
}
Hero::~Hero(void)
{
cout << "Hero destroyed!\n";
}
//Monsters.h
#pragma once
#include "Hero.h"
#include "Characters.h"
class Monsters:
public Characters //Hero
{
public:
Monsters(void);
Monsters(int, int, int, int);
//Monsters(int);
~Monsters(void);
};
//Monsters.cpp
int Monsterlevel;
int MonsterHp;
int MonsterStrength;
int MonsterAttack;
int MonsterDefense;
Monsters::Monsters(void)
{
"Monster Created";
}
Monsters::Monsters(int newHp, int newLevel, int newAttack, int newDef)
{
cout << "Monster created using Overloaded function!\n";
MonsterHp = newHp;
cout << "Hp is: "<< MonsterHp << endl;
Monsterlevel = newLevel;
cout << "level is: " << Monsterlevel << endl;
MonsterAttack = newAttack;
cout << "Attack is: " << MonsterAttack << endl;
MonsterDefense = newDef;
cout << "Defense is: " << MonsterDefense << endl;
}
Monsters::~Monsters(void)
{
cout << "\nMonster Destroyed";
}
//Characters.h
#pragma once
class Characters
{
private:
int level;
int Hp;
int Strength;
int Attack;
int Defense;
public:
Characters(void);
Characters(int);
Characters(int, int, int, int);
~Characters(void);
int getAttack();
int getDefense();
int getStrength();
int getHp();
int getLevel();
void setAttack(int);
void setDefense(int);
void setStrength(int);
void setHp(int);
void setlevel(int);
};
//Characters.cpp
Characters::Characters(void)
{
cout << "\nCharacter has been created!\n";
}
Characters::Characters(int random)//How can i make this work?
{
cout << "Level " << level << " character created with: \n";
/*srand ((unsigned)time(0));
random = rand() % 10 + 1;
setlevel(int random);*/
level = random;
}
Characters::~Characters(void)
{
cout << "Character has been destroyed!\n";
}
void Characters::setAttack(int att)//get Character left over hp
{
Attack = att;
}
void Characters::setDefense(int def)//get Character left over hp
{
Defense = def;
}
void Characters::setStrength(int str)//get Character left over hp
{
Strength = str;
}
void Characters::setHp(int damage)//get Character left over hp
{
Hp -= damage;
}
void Characters::setlevel(int lvl)//get Character left over hp
{
level = lvl;
}
int Characters::getAttack()
{
cout << "Your attack is: " << Attack << endl;
return Attack;
}
int Characters::getDefense()
{
cout << "Your defense is: " << Defense << endl;
return Defense;
}
int Characters::getStrength()
{
cout << "Your strength is: " << Strength << endl;
return Strength;
}
int Characters::getHp()
{
cout << "Your hp is: " << Hp << endl;
return Hp;
}
int Characters::getLevel()
{
cout << "Your level is: " << level << endl;
return level;
}
To start with, don't declare the variables global, declare them as member variables! When you declare a global variable, there will be only one instance of that variable in your program, so if you create (for example) two Monster object both will be using the same global variables.
You also don't create any monsters except one, m. The second time you call the Monster constructor you don't create a new Monster object, just call its constructor. After you make the variables member variables (by simply declaring them in the class) you can use the non-default constructor like this:
Monster m; // Uses default constructor
Monster m2(5, 6, 7, 8); // Uses the other constructor
As for the problem you have, it's that getHp method only returns a copy of the hitpoints, and so the statement doesn't actually do anything (it modifies the returned copy, then throw it away). Instead you should call the setHp method:
Me.setHp(Me.getHp() - m.getStrength());
There seems to be a disconnect with how you are understanding OOP (object oriented programming) and C++ programming.
In C++ (and C), you must declare everything before you use it. So if you have a class that you need to use, you must declare it first. Otherwise you will get an error.
In OOP programming, an object is an instance of a class definition. A class has several key components, though not all may be present:
Has a constructor:
This sets up the initial state of any new instance of the class and usually allocates resources used by the object.
Has a destructor:
This deallocates resources used by the object.
Has member variables:
This is how the resources or other state information are attached to the object.
Has member functions:
This is how you operate on the object.
Inherits from another class/struct:
This states an is-a relationship with another class/struct type. I.e. A car is-a vehicle, a bike is-a vehicle. Thus car and bike inherits from vehicle.
Now, your Hero.h file contains the class declaration Hero indicating it's constructors and destructor (BTW, you don't need the (void). That is old C style. In C++ an empty parameter list like () is equivalent to (void).), but it doesn't contain any member variables or functions. This is because you have inherited from Characters. Except that you have not declared Characters before you are using it as a base class. So in your Hero.h file, you must state #include "Character.h" before the declaration of the class. This goes for each header file.
BUT you should also have a guard around the contents of your header in case you include that file multiple times. To do that put something like this around the contents of Hero.h.
#if defined HERO_H
# define HERO_H
... the contents of Hero.h ...
#endif
Do this for each of you header files. Use a UNIQUE guard name for each file. I.e. don't use HERO_H for your Character.h file. NOTE I just noticed you are using #pragma once. This is equivalent to using the guard but is not portable across all compilers.
Going into your Hero.cpp file, there are a few things wrong.
You need to include the Hero.h file.
Remember that C++ is declare before use and each source file is compiled separately. Therefore you must declare everything that is used by each source file before you use it. Since the Hero class is declared in the Hero.h header file, you must include that header file.
Global variables:
I see you are using global variables. Don't do that, not when you have member variables that are supposed to do the same thing. A member variable is part of every instance of that class. In other words, every time you create an instance of the class, you will have a unique memory storage location for that member variable allowing you to have multiple instances that will have different states which don't conflict with each other. I.e.:
Hero::Hero(int newHp, int newLevel, int newAttack, int newDef)
{
cout << "Hero created using Overloaded function!\n";
Hp = newHp;
cout << "Hp is: "<< Hp << endl;
level = newLevel;
cout << "level is: " << level << endl;
Attack = newAttack;
cout << "Attack is: " << Attack << endl;
Defense = newDef;
cout << "Defense is: " << Defense << endl;
}
You also have a default constructor (it not called a 'normal' constructor) for Hero. Why? What is the point of having this? If there is a point, what are the defaults that need to be set for it? Looking at the Character class, I see that you also have not initialised the member variables for the instance either when you call its default constructor. I think the problem you are having here is that you don't know how to initialise an object which inherits from another, which is reasonable since it's not immediately obvious. Look at my last code fragment, and compare it to this new one:
Hero::Hero(int newHp, int newLevel, int newAttack, int newDef)
: Character(newHp, newLevel, newAttack, newDef) // <== initialiser list
{
cout << "Hero created using Overloaded function!\n";
cout << "Hp is: "<< Hp << endl;
cout << "level is: " << level << endl;
cout << "Attack is: " << Attack << endl;
cout << "Defense is: " << Defense << endl;
}
By using the initialiser list, I am initialising the base object by calling it's constructor that takes parameters. Doing it this way removes the need to have a base class that must have a default constructor or you can use the default constructor to generate the random values that you are looking for when calling its constructor that takes a single int value, thus removing the need for that constructor. For a description on how to use the rand() function, see here.
An initialiser list is just that, a list used to initialise the object. Thus it can contain multiple things (hence why it's called a list). The other things it can contain are initial values of member variables.
Characters::Characters(int newHp, int newLevel, int newAttack, int newDef)
: Hp(newHp), level(newLevel) //... etc
{
}
These need to be in the order of base class initialiser (like in the Hero example) and then the member variables in the order that they appear in the class declaration. Some compilers will allow this to be in any order, but again, this is not portable and may result in unexpected behaviour.
Oh, one other thing I noticed is that your Monster.h file includes Hero.h. Why? Does the Monster.h file use an instance of Hero? No. So get rid of it.