This code isn't compiled. All problems in virtual function attack() in basic class.
It hasn't got acces to massive in class Team. I was trying do theese classes friend.But it do not work whatever. Also I've done function ptr but it don't work.
Virtual function don't work in inherited classes too. Visual studio 2015 shows errors:
C2228, C2227, C2027.
Please help.
class Team;
class Unit
{
protected:
int hp;
int dmg;
int doodge;
public:
Unit(int hp, int dmg, int doodge): hp(hp), dmg(dmg), doodge(doodge){}
int GetHP()
{
return hp;
}
void SetHP(int hp)
{
this->hp = hp;
}
virtual void attack(Team &T)
{
int id = rand() % 3;
for (int i = 0; i < 3; i++)
if (typeid(*this) == typeid(T.arr[i]))
{
id = i;
break;
}
if (T.arr[id] <= 0)
return;
else
T.arr[id]->SetHP(T.arr[id]->GetHP() - this->dmg);
}
};
class Swordsman:public Unit
{
public:
Swordsman():Unit(15,5,60){}
//virtual void attack(Team & T)override
//{
// int id = rand() % 3;
// for (int i = 0; i < 3; i++)
// if (typeid(Swordsman) == typeid())
// {
// id = i;
// break;
// }
// if (*T.arr[id]->GetHP <= 0)
// return;
// else
// *T.arr[id]->SetHP(T.arr[id]->GetHP() - dmg);
//}
};
class Archer :public Unit
{
public:
Archer() :Unit(12, 4, 40) {}
//virtual void attack(Team & T)override
//{
// int id = rand() % 3;
// for (int i = 0; i < 3; i++)
// if (typeid(Archer) == typeid())
// {
// id = i;
// break;
// }
// if (*T.arr[id]->GetHP <= 0)
// return;
// else
// *T.arr[id]->SetHP(T.arr[id]->GetHP() - dmg);
//}
};
class Mage :public Unit
{
public:
Mage() :Unit(8, 10, 30) {}
/*virtual void attack(Team & T)override
{
int id = rand() % 3;
for (int i = 0; i < 3; i++)
if (typeid(*this) == typeid())
{
id = i;
break;
}*/
};
class Team
{
static short counter;
string name;
Unit* arr[3];
public:
Team()
{
name = "Team " + counter++;
for (int i = 0; i < 3; i++)
{
int selecter = rand() % 3;
switch (selecter)
{
case 0:
arr[i] = new Swordsman();
break;
case 1:
arr[i] = new Archer();
break;
case 2:
arr[i] = new Mage();
break;
}
}
}
~Team()
{
delete[]arr;
}
Unit * ptr(int id)
{
return arr[id];
}
bool check()
{
bool res = false;
for (int i = 0; i < 3; i++)
if (arr[i]->GetHP() > 0)
res = true;
return res;
}
void print()
{
cout << endl << "\t\t" << name << endl << endl;
cout << "\t" << typeid(*arr[0]).name() << endl;
cout << "\t" << typeid(*arr[1]).name() << endl;
cout << "\t" << typeid(*arr[2]).name() << endl;
}
friend class Unit;
};
short Team::counter = 0;
class Game
{
Team A, B;
public:
int Play()
{
while (true)
{
A.ptr(1)->attack(B);
if (A.check())
return 1;
else if (B.check())
return 2;
}
}
};
int main()
{
return 0;
}
Omitting anything irrelevant:
class Team;
class Unit
{
public:
virtual void attack(Team &T)
{
if(typeid(*this) == typeid(T.arr[i]))
// ^^^
{ }
}
};
You are accessing a member of class Team, but at the time given, you only have provided the declaration of Team... Side note: this is not specific to virtual functions, but would occur with any code you write.
Your problem now is that function implementations of both classes Team as well as Unit rely on the complete definition of the other class. So only solution to the problem is to implement one of the functions outside the class, e. g.:
class Team;
class Unit
{
public:
// requires Team, so only declared, not implemented!
virtual void attack(Team &T);
// ^
};
class Team
{
// complete definition!
};
void Unit::attack(Team& t)
{
// now implementation of...
}
Another minor problem is that arr member is private. Well, you provided a getter already (ptr), so use it (and give it a better name...).
If you want to go further towards a clean design, split your units and the team into different compilation units, each coming with a header and a source file:
unit.h:
class Team;
class Unit
{
// private members
public:
// only declarations as above, including constructor/destructor
// by the way: you are lacking a virtual destructor!!!
virtual ~Unit();
};
unit.cpp:
#include "unit.h"
#include "team.h" // fetch the definition of Team!
Unit(/*...*/) { }
Unit::~Unit() { }
// function definitions as shown above...
You would do the same for Team and even your Unit derived classes as well as the Game class. Be aware, though, that you need the complete class definition available if you want to inherit, so you need to include unit.h already int the headers:
archer.h:
#include "unit.h"
class Archer : public Unit
{
// again, only function declarations...
// as base class has already a virtual destructor, own destructor
// gets virtual implicitly (even the default one), so if you do
// not need it, you do not have to define it...
};
archer.cpp:
#include "archer.h"
// and whatever else needed, solely, unit.h already comes with archer.h
// implementations...
Related
So in my program, I'm using polymorphism, which could also explain some of the issues that I'm having.
This is my pure abstract class:
class Event {
public:
Event();
~Event();
virtual int returnType();
};
Then I have a room class that sets events to a particular room:
class Room {
private:
Event * e;
bool player = false;
bool bEvent = false;
public:
Room();
~Room();
Event * getEvent();
void setEvent(Event *);
bool getPlayer();
void setPlayer(bool);
bool getBoolEvent();
void setBoolEvent(bool);
};
And here are my function definitions:
Event * Room::getEvent() {
return e;
}
void Room::setEvent(Event * n) {
e = n;
}
bool Room::getPlayer() {
return player;
}
void Room::setPlayer(bool p) {
player = p;
}
bool Room::getBoolEvent() {
return bEvent;
}
void Room::setBoolEvent(bool b) {
bEvent = b;
}
Here is my bats class which is a derived class from event: The functions are the same, so here are the function definitions:
int Bats::returnType() {
return 1;
}
So in my program, I am using a 2d vector of Rooms, and then assigning events to these rooms via polymorphism. The problem is that I don't think the changes are persisting, at least with the polymorphism, even when passing by reference.
Here is the function where I am setting the bat event to a certain room in the 2d vector:
vector<vector<Room>> Game::setEvents(vector<vector<Room>> &grid) {
Bats b1;
Event * eb1 = &b1;
//Set player
int r1 = rand()%gridSize;
int r2 = rand()%gridSize;
grid[r1][r2].setPlayer(true);
//Set bats
grid[0][0].setBoolEvent(true);
grid[0][0].setEvent(eb1);
cout << "Function example: " << grid[0][0].getEvent()->returnType() << endl;
return grid;
}
As an output I get Function example: 1;
However, when we move into the main (in this case Game::play()) function, these changes don't hold.
void Game::play() {
srand(time(NULL));
//Create vector
vector<vector<Room>> grid;
//Fill vector
fillGrid(grid);
//Set player and events
grid = setEvents(grid);
for (int i = 0; i < gridSize; i++) {
for (int j = 0; j < gridSize; j++) {
if (grid[i][j].getBoolEvent() == true) {
cout << i << " " << j << endl;
cout << grid[i][j].getEvent()->returnType() << endl;
}
}
}
}
As an output I get 0 0 and then a seg fault.
Although the boolEvent is still true, for some reason I get a segmentation fault when trying to call returnType(), even though it worked in the setEvents() function. What am I doing wrong with polymorphism?
I have an abstract class "Mark" and it has a child class "Int_num". I also have a "Subject" class. I want a pointer to the address in the memory of the "Mark" class to be written to the "mark" parameter when calling its constructor. What should I do to make the mark pointer point to the "Mark" class?" occurred, after the compiler complaint about "expression must have class type" or something like that in mark.print_mark()?
class Mark {
private:
int mark;
public:
virtual void change_mark(int);
virtual void print_mark();
virtual int return_mark();
};
class Int_mark : public Mark {
private:
int mark;
public:
Int_mark();
Int_mark(int);
~Int_mark();
void change_mark(int = 0);
void print_mark() const;
int return_mark() const;
};
Int_mark::Int_mark() {
std::string str_mark;
std::cout << "New mark: ";
std::cin.ignore();
std::getline(std::cin, str_mark);
str_mark = ltrim(rtrim(str_mark));
int new_mark;
try {
new_mark = stoi(str_mark);
} catch(...) {
std::cout <<"wq";
mark = 1;
return ;
}
try {
if((new_mark < 1) || (new_mark > 5))
throw 1;
else
mark = new_mark;
} catch(int a) {
std::cout << "qw" << std::endl;
mark = 1;
}
}
void Int_mark::print_mark() const {
std::cout << "Mark: " << mark << std::endl;
}
Subject
#include "Mark.h"
#include <string>
#include <vector>
class Subject {
private:
std::string name_subject;
std::string type_subject;
unsigned hour_subject = 0;
void *mark = nullptr;
public:
Subject();
Subject(std::string, int);
Subject(std::string, bool);
~Subject();
void change_mark(unsigned);
void change_mark(bool);
void rename_subj(std::string);
void add_hour(unsigned);
};
Subject::Subject() {
std::string name_sub;
std::cout << "Введите название предмета: ";
getline(std::cin, name_sub);
name_sub = split_string(name_sub);
name_subject = name_sub;
int select = 2;
if(select == 1) {
type_subject = "Bool";
//mark = new Bool_mark();
} else {
type_subject = "Int";
mark = new Int_mark();
//What should I do to make the mark pointer point to the "Mark" class?
mark.print_mark();
}
}
main
#include "subject/Subject.h"
using namespace std;
int main() {
Subject q;
}
What am I doing wrong? How should I do this?
The pointer mark is of type void *. You could cast it with
static_cast<Int_mark*>(mark)
and call the function with
static_cast<Int_mark*>(mark)->print_mark();
But usually in OOP mark would be a pointer to the base class
Mark *mark = nullptr;
Now you can check for errors with
mark = new Int_mark();
auto *m = dynamic_cast<Int_mark*>(mark);
if (m)
m->print_mark();
Remember the virtual destructor in the base class
virtual ~Mark();
When to use virtual destructors?
Here is a fixed version of your code:
#include <iostream>
#include <string>
#include <vector>
class Mark {
public:
virtual ~Mark() = default;
//virtual void change_mark(int) = 0;
virtual void print_mark() const = 0;
//virtual int return_mark() const = 0;
};
class Int_mark : public Mark {
private:
int mark;
public:
Int_mark();
Int_mark(int);
~Int_mark() override = default;
//void change_mark(int = 0) override;
void print_mark() const override;
//int return_mark() const override;
};
Int_mark::Int_mark() {
std::string str_mark;
std::cout << "New mark: ";
std::cin.ignore();
std::getline(std::cin, str_mark);
//str_mark = ltrim(rtrim(str_mark));
int new_mark;
try {
new_mark = stoi(str_mark);
} catch(...) {
std::cout <<"wq";
mark = 1;
return ;
}
try {
if((new_mark < 1) || (new_mark > 5))
throw 1;
else
mark = new_mark;
} catch(int a) {
std::cout << "qw" << std::endl;
mark = 1;
}
}
void Int_mark::print_mark() const {
std::cout << "Mark: " << mark << std::endl;
}
class Subject {
private:
std::string name_subject;
std::string type_subject;
unsigned hour_subject = 0;
Mark *mark = nullptr;
public:
Subject();
Subject(std::string, int);
Subject(std::string, bool);
~Subject();
void change_mark(unsigned);
void change_mark(bool);
void rename_subj(std::string);
void add_hour(unsigned);
};
Subject::Subject() {
std::string name_sub;
std::cout << "Введите название предмета: ";
getline(std::cin, name_sub);
//name_sub = split_string(name_sub);
name_subject = name_sub;
int select = 2;
if(select == 1) {
type_subject = "Bool";
//mark = new Bool_mark();
} else {
type_subject = "Int";
mark = new Int_mark();
auto *m = dynamic_cast<Int_mark*>(mark);
if (m)
m->print_mark();
}
}
Subject::~Subject() {
delete mark;
}
int main() {
Subject q;
}
Since I did not correctly understand the question in the first place, here a way how you can call the member function of base class Mark by object of derived class Int_Mark:
Int_mark *mark = new Int_mark();
mark->print_mark(); // calls member of the class Int_mark
mark->Mark::print_mark(); // calls member of the class Mark
Make sure that Mark::print_mark() is also defined and not just Int_mark::print_mark()
I am trying to implement a card game in c++ using VS-2013, and I have a "Player" class.
The "Player" class is abstract in the sense that no actual objects of that class are to be initialized. Instead, it is only there to be inherited to 4 different player classes (with 4 different playing strategies) - "PlayerType1" to "PlayerType4".
This is my Player.h file:
#ifndef PLAYER_H_
#define PLAYER_H_
#include <iostream>
#include "Hand.h"
using namespace std;
class Player : public Hand {
private:
const string name;
protected:
Hand myHand;
public:
string getName(); //Returns the name of the player
virtual int getShapeToAsk() = 0;
virtual int getPlayerToAsk() = 0;
virtual ~Player();
};
class PlayerType1 : public Player { //For strategy 1
PlayerType1();
virtual int getShapeToAsk() override;
virtual int getPlayerToAsk() override;
~PlayerType1();
};
class PlayerType2 : public Player { //For strategy 2
PlayerType2();
virtual int getShapeToAsk() override;
virtual int getPlayerToAsk() override;
~PlayerType2();
};
class PlayerType3 : public Player { //For strategy 3
private:
int myNumber, numOfPlayers, nextPlayer;
public:
PlayerType3(int myNumber, int numOfPlayers);
virtual int getShapeToAsk() override;
virtual int getPlayerToAsk() override;
~PlayerType3();
};
class PlayerType4 : public Player { //For strategy 4
private:
int myNumber, numOfPlayers, nextPlayer;
public:
PlayerType4(int myNumber, int numOfPlayers);
virtual int getShapeToAsk() override;
virtual int getPlayerToAsk() override;
~PlayerType4();
};
#endif
And this is my Player.cpp file:
#include <iostream>
#include <vector>
#include "Hand.h"
#include "Player.h"
using namespace std;
//Player functions
string Player::getName(){
return (this->name + " " + this->toString());
}
Player::~Player(){}
//PlayerType1 functions
PlayerType1::PlayerType1(){}
int PlayerType1::getShapeToAsk(){
int maxCount = 0, maxValue, currValue, count;
for (std::vector<Card*>::reverse_iterator i = this->myHand.getCards().rbegin(); i != this->myHand.getCards().rend(); i++){
count = 1;
currValue = (**i).getValue();
for (i; (i != this->myHand.getCards().rend()) && ((**i).getValue() == currValue); ++i){
count++;
}
if (count > maxCount){
maxCount = count;
maxValue = currValue;
if (maxCount == 4) // no need to look at the rest of the hand
break;
}
}
return maxValue;
}
int PlayerType1::getPlayerToAsk(){ return -1; } //-1 means "I am a player of type 1 or 2". Game's responsibility to change later.
PlayerType1::~PlayerType1(){}
//PlayerType2 functions
PlayerType2::PlayerType2(){}
int PlayerType2::getShapeToAsk(){
int minCount = 5, minValue, currValue, count;
for (std::vector<Card*>::iterator i = this->myHand.getCards().begin(); i != this->myHand.getCards().end(); i++){
count = 1;
currValue = (**i).getValue();
for (i; (i != this->myHand.getCards().end()) && ((**i).getValue() == currValue); ++i){
count++;
}
if (count < minCount){
minCount = count;
minValue = currValue;
if (minCount == 1) // no need to look at the rest of the hand
break;
}
}
return minValue;
}
int PlayerType2::getPlayerToAsk(){ return -1; } //-1 means "I am a player of type 1 or 2". Game's responsibility to change later.
PlayerType2::~PlayerType2(){}
//PlayerType3 functions
PlayerType3::PlayerType3(int myNumber, int numOfPlayers){
this->myNumber = myNumber;
this->numOfPlayers = numOfPlayers;
if (myNumber == 1) this->nextPlayer = 2;
else this->nextPlayer = 1;
}
int PlayerType3::getShapeToAsk(){
int maxCount = 0, maxValue, currValue, count;
for (std::vector<Card*>::reverse_iterator i = this->myHand.getCards().rbegin(); i != this->myHand.getCards().rend(); i++){
count = 1;
currValue = (**i).getValue();
for (i; (i != this->myHand.getCards().rend()) && ((**i).getValue() == currValue); ++i){
count++;
}
if (count > maxCount){
maxCount = count;
maxValue = currValue;
if (maxCount == 4) // no need to look at the rest of the hand
break;
}
}
return maxValue;
}
int PlayerType3::getPlayerToAsk(){
int temp = this->nextPlayer;
this->nextPlayer++;
while ((this->nextPlayer == this->myNumber) || (this->nextPlayer > this->numOfPlayers)){
if (this->nextPlayer == this->myNumber) this->nextPlayer++;
if (this->nextPlayer > this->numOfPlayers) this->nextPlayer = 1;
}
return temp;
}
PlayerType3::~PlayerType3(){}
//PlayerType4 functions
PlayerType4::PlayerType4(int myNumber, int numOfPlayers){
this->myNumber = myNumber;
this->numOfPlayers = numOfPlayers;
if (myNumber == 1) this->nextPlayer = 2;
else this->nextPlayer = 1;
}
int PlayerType4::getShapeToAsk(){
int minCount = 5, minValue, currValue, count;
for (std::vector<Card*>::iterator i = this->myHand.getCards().begin(); i != this->myHand.getCards().end(); i++){
count = 1;
currValue = (**i).getValue();
for (i; (i != this->myHand.getCards().end()) && ((**i).getValue() == currValue); ++i){
count++;
}
if (count < minCount){
minCount = count;
minValue = currValue;
if (minCount == 1) // no need to look at the rest of the hand
break;
}
}
return minValue;
}
int PlayerType4::getPlayerToAsk(){
int temp = this->nextPlayer;
this->nextPlayer++;
while ((this->nextPlayer == this->myNumber) || (this->nextPlayer > this->numOfPlayers)){
if (this->nextPlayer == this->myNumber) this->nextPlayer++;
if (this->nextPlayer > this->numOfPlayers) this->nextPlayer = 1;
}
return temp;
}
PlayerType4::~PlayerType4(){}
I get the following errors:
Error error C2512: 'Player' : no appropriate default constructor available <PATH>\player.cpp
A total of 4 errors of that type, each pointing to the constructors of PlayerType1 to PlayerType4.
When I add an empty default constructor to my "Player" class, it solves the problem and I get a successful build.
However, I fail to see why I need to define a default constructor for the "Player" class, as I never initialize an object of that class.
I should also mention I have another class in my project ("Card" class) that is abstract and is just there to be inherited by other classes ("FigureCard" and "NumericCard"), and also has no constructor, and the derived classes have their own constructors, and that causes no error. I fail to see the difference.
I searched other questions, but they all relate to cases in which a default constructor was not defined, and an initialization was attempted of that class elsewhere in the code. That is not my case since I am not initializing an object of class "Player", only the 4 derived classes.
Please help!
Thank you in advance.
Even if your Player class is abstract, you must define a constructor because your class has members. When you create an instance of a derived class (any of your PlayerType) class, it will call the constructor of the base class. This is how inheritence works...
In that case, make it protected (making it public would be useless anyway because it's a pure virtual class).
Your Player class has a private: const string name; member. Look at your Card class; I bet it does not have such a member. That's the difference.
The thing is, the const string name; member must somehow be initialized, and since it is private, it must be initialized within the Player class. (Language rules prohibit the initialization of a private member of a class from a derived class.) Therefore, the Player class must have a constructor which will initialize the name member. The empty constructor achieves this.
Recently, I started working with classes and, today, class inheritance. I created a simple program to expand my perception of inheritance. The program calculates the average grade of a class. I understand the vast majority of the code I have written, but there are some exceptions (listed below the code). Any and all help would be appreciated.
Code
#include "stdafx.h"
#include <iostream>
using namespace std;
class CAverage {
private:
double VSubCount, VAverage, VMark, VSum, VNum;
public: CAverage(int); // Constructor.
void MTake_action() {
MAsk_input(); // Calls the method “MAsk_input()“ within this class.
MCalculate_average(); // Calls the method “MCalculate_average()“ within
// this class.
MPrint_result(); // Calls the method “MPrint_result()“ within this class.
}
void MCalculate_average() {
VAverage = VSum / VNum;
}
void MAsk_input() {
VSum = 0;
VNum = 0;
int VNumber;
for (int i = 0; i < VSubCount; i++) {
cout << "Enter your " << i + 1 << " mark: ";
cin >> VNumber;
if (VNumber > 0) {
VMark = VNumber;
VSum += VMark;
VNum++;
}
}
}
void MPrint_result()
{
system("cls");
if (((VSum / 3) <= 0) || ((VSum / 3) > 10)) {
cout << "Incorrect input." << endl;
} else {
cout << "Average: " << VAverage << endl;
}
}
};
// Creates a child class and makes that this class could view/get public methods,
// variables, etc of “CAverage“.
class CGroup : public CAverage {
private:
int VClassMembers;
void MAsk_input() {
for (int i = 0; i < VClassMembers; i++) {
system("cls");
cout << "[" << i + 1 << " student]" << endl;
CAverage::MAsk_input(); // Calls the method “MAsk_input()“ within
// the parent class (“CAverage“).
}
}
public: CGroup(int, int);
void MTake_action() {
MAsk_input(); // Calls the method “MAsk_input()“ within this class.
CAverage::MCalculate_average(); // Calls the method “MCalculate_average()“
// within the parent class (“CAverage“).
CAverage::MPrint_result(); // Calls the method “MPrint_result()“ within the
// parent class (“CAverage“).
}
};
CAverage::CAverage(int VSubjectCount) {
VSubCount = VSubjectCount;
}
CGroup::CGroup(int VOther, int VInteger) : CAverage(VOther) {
VClassMembers = VInteger;
}
int main() {
CGroup avg(2, 5); // Creates an object, named “avg“.
avg.MTake_action(); // Calls the child classes' method “MTake_action()“.
return 0;
}
So, how would one explain these parts?
CAverage::CAverage(int VSubjectCount) {
VSubCount = VSubjectCount;
}
CGroup::CGroup(int VOther, int VInteger) : CAverage(VOther) {
VClassMembers = VInteger;
}
I think that this
CAverage(int);
and this
CGroup(int, int);
call the constructors? Or, are they themselves the constructors?
And, are all of the comments, made by me, correct?
I think that this
CAverage(int);
and this
CGroup(int, int);
call the constructors? Or, are they themselves the constructors?
Your second presumption is correct, both are constructors.
CAverage::CAverage(int VSubjectCount) {
VSubCount = VSubjectCount;
}
This snippet initializes the variable VSubCount within the superclass.
CGroup::CGroup(int VOther, int VInteger) : CAverage(VOther) {
VClassMembers = VInteger;
}
This is a little more complex, and shows key concepts of inheritance.
: CAverage(VOther)
Is calling the parent constructor, to initialize the private member VSubCount, in CAverage, since CGroup cannot access it.
VClassMembers = VInteger;
initializes the member VClassMembers in the subclass. Otherwise, your comments are correct.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
My first question is: I am having a lot of trouble figuring out why the Example class is being constructed greater than the others. Below is a short app using a Template counter to track how many times the constructor/destructor/copy constructor is called for each class. There are a total of three classes: Example, Deep, Child. Each has a copy constructor... ugh.
Also, my second question, is what would be the correct way to define the copy constructor for the Child class?
In the printStatus(), it displays:
COUNTERS::NEW_COUNTER = 60
COUNTERS::DELETE_COUNTER = 50
COUNTERS::CONSTRUCTOR_COUNTER = 90
COUNTERS::DESTRUCTOR_COUNTER = 80
Example count = 10
Deep count = 0
Child count = 0
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class COUNTERS
{
public:
static int NEW_COUNTER;
static int DELETE_COUNTER;
static int CONSTRUCTOR_COUNTER;
static int DESTRUCTOR_COUNTER;
};
int COUNTERS::NEW_COUNTER = 0;
int COUNTERS::DELETE_COUNTER = 0;
int COUNTERS::CONSTRUCTOR_COUNTER = 0;
int COUNTERS::DESTRUCTOR_COUNTER = 0;
/* template used for counting constructors/destructors to debug memory leaks */
template <typename T>
class Countable
{
static unsigned cs_count_;
public:
Countable() { ++cs_count_; }
Countable( Countable const& ) { ++cs_count_; }
virtual ~Countable() { --cs_count_;}
static unsigned count() { return cs_count_; }
};
template <typename T>
unsigned Countable<T>::cs_count_ = 0;
class Example : public Countable<Example>
{
public:
string a;
int b;
Example() {
COUNTERS::CONSTRUCTOR_COUNTER++;
a = "exampleString";
b = 5;
}
virtual ~Example() {
COUNTERS::DESTRUCTOR_COUNTER++;
}
// copy constructor
Example(const Example& e) {
COUNTERS::CONSTRUCTOR_COUNTER++;
this->a = e.a;
this->b = e.b;
}
};
class Deep : public Countable<Deep>
{
public:
int a;
string b;
Example* e;
Deep()
{
COUNTERS::CONSTRUCTOR_COUNTER++;
a = 3;
b = "deepString";
e = new Example();
COUNTERS::NEW_COUNTER++;
}
virtual ~Deep() {
if(e != NULL) {
delete e;
COUNTERS::DELETE_COUNTER++;
}
COUNTERS::DESTRUCTOR_COUNTER++;
}
// copy constructor
Deep(const Deep& x)
{
COUNTERS::CONSTRUCTOR_COUNTER++;
this->a = x.a;
this->b = x.b;
this->e = new Example();
COUNTERS::NEW_COUNTER++;
this->e->a = x.e->a;
this->e->b = x.e->b;
};
};
class Child : public Countable<Child>
{
public:
Deep d;
string name;
int age;
Example* e;
vector<Example> list;
vector<Deep> deep_list;
void init()
{
Deep* var = new Deep(); COUNTERS::NEW_COUNTER++;
deep_list.push_back(*var);
delete var; COUNTERS::DELETE_COUNTER++;
}
Child() {
COUNTERS::CONSTRUCTOR_COUNTER++;
name = "a";
age = 10;
d.a = 1;
d.b = "deep";
d.e = NULL;
e = new Example();
COUNTERS::NEW_COUNTER++;
list.push_back(*e);
init();
}
virtual ~Child() {
COUNTERS::DESTRUCTOR_COUNTER++;
if(e != NULL) {
delete e;
COUNTERS::DELETE_COUNTER++;
}
}
// copy constructor
Child(const Child& c)
{
}
};
void myChildFunction(){
Child* c = new Child();
COUNTERS::NEW_COUNTER++;
delete c;
COUNTERS::DELETE_COUNTER++;
}
void printStatus(){
cout << "COUNTERS::NEW_COUNTER = " << COUNTERS::NEW_COUNTER << endl;
cout << "COUNTERS::DELETE_COUNTER = " << COUNTERS::DELETE_COUNTER << endl;
cout << "COUNTERS::CONSTRUCTOR_COUNTER = " << COUNTERS::CONSTRUCTOR_COUNTER << endl;
cout << "COUNTERS::DESTRUCTOR_COUNTER = " << COUNTERS::DESTRUCTOR_COUNTER << endl;
cout << "Example count = " << Example::count() << endl;
cout << "Deep count = " << Deep::count() << endl;
cout << "Child count = " << Child::count() << endl;
}
int main()
{
for(unsigned int i=0 ; i < 10; i++)
myChildFunction();
printStatus();
return 0;
}
You are missing out on deleting some Example objects because of this line:
d.e = NULL;
in Child::Child().
You are allocating memory for e in the constructor of Deep. After executing the above line, that memory is leaked.
You can resolve that problem by:
Removing that line (or commenting it out),
Deleting d.e before making it NULL, or
Doing something else that prevents the memory leak.
Update, in response to comment
Copy constructor for Child:
Child(const Child& c) : d(c.d),
name(c.name),
age(c.age),
e(new Example(*c.e)),
list(c.list),
deep_list(c.deep_list)
{
COUNTERS::DESTRUCTOR_COUNTER++; // This is for Child
COUNTERS::NEW_COUNTER++; // This is for new Example
}
I removed all information that cluttered your code.
When using templates, constructors and copy constructors NEED the following: Example < eltType >(void);
in the class definition. All objects that inherit from Countables are known as derived classes. They also may call a derived class a child, and the class in which it is derived from is called the parent. I added the COPY_CONSTRUCTOR_COUNT to add clarification to the data which is being presented on the console/command prompt. Usually when trying to preform a task, large or small, doing it incrementally and by providing methods, for each task, saves you time and a headache. I removed the new_count and delete_count from the equation, because I felt that it was not needed.
You will notice that I added : Countable( * ((Countable < eltType > *)&e))
This is a requirement when designing a program that involves inheritance, which introduces the
topic of Polymorphism :D
What that bit of code does is that it gets a pointer of a Countable, which will point to the address of object e, which then allows access to all super classes of this class, but not including e's class.
NOTE: Since e is a derived class of Countable, this is valid statement.
For you second question, all of your data members are public, you can use an iterator to copy your data stored in you vectors.
As a concern from one programmer to another, I hope your code in practice is well documented, and all methods declared in your class are defined in a .cpp file.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class COUNTERS
{
public:
static int NEW_COUNTER;
static int DELETE_COUNTER;
static int CONSTRUCTOR_COUNTER;
static int DESTRUCTOR_COUNTER;
static int COPY_CONSTRUCTOR_COUNTER;
};
int COUNTERS::NEW_COUNTER = 0;
int COUNTERS::DELETE_COUNTER = 0;
int COUNTERS::CONSTRUCTOR_COUNTER = 0;
int COUNTERS::DESTRUCTOR_COUNTER = 0;
int COUNTERS::COPY_CONSTRUCTOR_COUNTER = 0;
/* template used for counting constructors/destructors to debug memory leaks */
template <typename T>
class Countable
{
public:
Countable<T>()
{
incrementObjectCount();
};
Countable<T>(Countable const&)
{
incrementObjectCount();
};
virtual ~Countable()
{
decrementObjectCount();
};
static unsigned count()
{
return cs_count_;
};
protected:
static unsigned cs_count_;
////////////////////////////////////ADDED////////////////////////////////////
protected:
void incrementObjectCount(void){ ++cs_count_; };
void decrementObjectCount(void){ --cs_count_; };
void incrementDeconstructorCounter(void){ ++COUNTERS::DESTRUCTOR_COUNTER; };
/////////////////////////////////////ADDED////////////////////////////////////
};
template <typename T>
unsigned Countable<T>::cs_count_ = 0;
class Example : public Countable<Example>
{
public:
Example() : Countable<Example>()
{
COUNTERS::CONSTRUCTOR_COUNTER++;
}
virtual ~Example()
{
incrementDeconstructorCounter();
}
// copy constructor
Example(const Example& e) : Countable<Example>(*((Countable<Example>*)&e))
{
// COUNTERS::CONSTRUCTOR_COUNTER++; This is copy constructor, you addmitted this from "Child" class CCstr
++COUNTERS::COPY_CONSTRUCTOR_COUNTER; // For even more information added this
}
};
class Deep : public Countable<Deep>
{
public:
Deep() : Countable<Deep>()
{
COUNTERS::CONSTRUCTOR_COUNTER++;
}
virtual ~Deep()
{
COUNTERS::DESTRUCTOR_COUNTER++;
}
// copy constructor
Deep(const Deep& x) : Countable<Deep>(*((Countable<Deep>*)&x))
{
//COUNTERS::CONSTRUCTOR_COUNTER++;
++COUNTERS::COPY_CONSTRUCTOR_COUNTER; // For even more information added this
};
};
class Child : public Countable<Child>
{
public:
vector<Example> list;
vector<Deep> deep_list;
void init()
{
deep_list.push_back(Deep());
list.push_back(Example());
}
Child() : Countable<Child>()
{
COUNTERS::CONSTRUCTOR_COUNTER++;
init();
}
virtual ~Child()
{
COUNTERS::DESTRUCTOR_COUNTER++;
}
// copy constructor
Child(const Child& c) : Countable<Child>(*((Countable<Child>*)&c))
{
++COUNTERS::COPY_CONSTRUCTOR_COUNTER; // For even more information added this
}
};
void myChildFunction(){
Child* c = new Child();
//COUNTERS::NEW_COUNTER++;not needed
delete c;
//COUNTERS::DELETE_COUNTER++; not need
}
void printStatus(){
cout << "COUNTERS::NEW_COUNTER = " << COUNTERS::NEW_COUNTER << endl;
cout << "COUNTERS::DELETE_COUNTER = " << COUNTERS::DELETE_COUNTER << endl;
cout << "COUNTERS::CONSTRUCTOR_COUNTER = " << COUNTERS::CONSTRUCTOR_COUNTER << endl;
cout << "COUNTERS::DESTRUCTOR_COUNTER = " << COUNTERS::DESTRUCTOR_COUNTER << endl;
cout << "COUNTERS::COPY_CONSTRUCTOR_COUNTER = " << COUNTERS::COPY_CONSTRUCTOR_COUNTER << endl;
cout << "Example count = " << Example::count() << endl;
cout << "Deep count = " << Deep::count() << endl;
cout << "Child count = " << Child::count() << endl;
}
int main()
{
for (unsigned int i = 0; i < 10; i++)
myChildFunction();
printStatus();
system("pause");
return 0;
}