Decorator Design Pattern, Segmentation fault [closed] - c++

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I want to implement the Decorator design pattern. However, my code gives me Segmentation fault error. I tried to compile it using the -g flag and then check it with gdb. gdb shows only that the error is somewhere inside the action method, but I do not understand where and why.
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
class CComponent
{
protected:
int * i_array;
int i_size;
public:
CComponent(int i_size)
{
this->i_size=i_size;
i_array= new int[i_size];
for(int i=0; i<i_size; i++)
{
i_array[i]=0;
}
}
virtual int action() = 0;
~CComponent()
{
delete i_array;
}
int get_i_size()
{
return i_size;
}
int get_array_at(int index)
{
return i_array[index];
}
};
class CConcreteCComponent : public CComponent
{
public:
CConcreteCComponent(int i_size) : CComponent(i_size) { }
int action()
{
for(int i=0; i<i_size; i++)
{
i_array[i] = rand() % 100;
cout<< i_array[i] << " " << endl;
}
return 0;
}
};
class Decorator : public CComponent
{
protected:
CComponent * c;
public:
Decorator(int i_size) : CComponent(i_size)
{
c = new CConcreteCComponent(100);
}
int action()
{
return c->action();
}
};
class CConcreteDecorator3 : public Decorator
{
public:
CConcreteDecorator3(int i_size) : Decorator(i_size)
{
}
int action()
{
int w = action();
for(int i=0; i<c->get_i_size(); i++)
if(c->get_array_at(i) % 2 == 0)
return w;
return w + 50;
}
};
class CConcreteDecorator1 : public Decorator
{
public:
CConcreteDecorator1(int i_size) : Decorator(i_size)
{
}
int action()
{
int w = action();
if(c->get_array_at(0) == 0 && c->get_array_at(i_size -1) == 0)
return w + 100;
return w;
}
};
class CConcreteDecorator2 : public Decorator
{
public:
CConcreteDecorator2(int i_size) : Decorator(i_size)
{
}
int action()
{
int w = action();
if(c->get_i_size() > 7)
return w + 150;
return w;
}
};
int main()
{
Decorator * d = new CConcreteDecorator3(100);
Decorator * d2 = new CConcreteDecorator1(100);
Decorator * d3 = new CConcreteDecorator2(100);
int res;
res = d->action();
cout << "res :" << res << endl;
return 0;
}

The reason is an infinite recusion.
In CConcreteDecorator3 in action method instead of:
int w = action();
You should probably use:
int w = Decorator::action();

Furthermore...
Your Decorator class leaks. You have no destructor with a delete.
It is considered good practice to use a std::vector<int> instead int * i_array and a std::unique_ptr for CComponent * c; Dont bother using new/delete unless you cannot avoid it.
Your CComponent needs a virtual destructor. You'll find a lot of explanations if you google polymorphism and virtual destructor.

Related

I'm getting an error saying that only virtual functions can be marked as override

I keep getting this error that only virtual functions can be marked as override but the functions in question "norm()" and "string to_string()" are virtual. what could be causing this?
In my main function I am also getting the error no matching member function to call push back, did I make a mistake along the way somewhere and I am just not seeing it?
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
class Group
{
public:
virtual string to_string() = 0;
virtual int norm() = 0;
};
class Real
{
// add your code here
protected:
int number;
public:
Real(int num)
{
number = num;
}
int norm() override
{
return number;
}
string to_string() override
{
return number;
}
int getNumber() const
{
return number;
}
void setNumber(int number)
{
Real::number = number;
}
};
class Complex : public Real
{
// add your code here
protected:
int imaginary;
public:
Complex(int realNum, int imag) : Real(realNum)
{}
int norm() override
{
return sqrt(number * number + imaginary * imaginary) + 'i';
}
string to_string() override
{
return ::to_string(number) + '+' + ::to_string(imaginary) + 'i';
}
};
class Trinomial : public Complex
{
// add your code here
protected:
int third;
public:
Trinomial(int p1, int p2, int p3) : Complex(p1, p2) {
third = p3;
}
int norm() override {
return sqrt(number * number + imaginary * imaginary + third * third);
}
string to_string() override {
return ::to_string(number) + "x^2+" + ::to_string(imaginary) + "x+" + ::to_string(third);
}
};
class Vector : public Group
{
// add your code here
protected:
vector<int> v;
public:
Vector(int num1, int num2, int num3)
{
v.push_back(num1);
v.push_back(num2);
v.push_back(num3);
}
int norm() override
{
int squared_sum = 0;
for (int i = 0; i < v.size(); i++) {
squared_sum += v[i] * v[i];
}
return sqrt(squared_sum);
}
string to_string() override
{
string str = "[";
for (int i = 0; i < v.size() - 1; i++) {
str += ::to_string(v[i]) + " ";
}
str += ::to_string(v[v.size() - 1]) + "]";
return str;
}
};
int main()
{
vector<Group*> elements;
elements.push_back(new Real{ 3 });
elements.push_back(new Complex{ 3,4 });
elements.push_back(new Trinomial{ 1,2,3 });
elements.push_back(new Vector{ 1,2,3 });
for (auto e : elements)
{
cout << "|" << e->to_string() << "| = " << e->norm() << endl;
}
for (auto e : elements)
delete e;
return 0;
}
A couple of issues here:
The class Real must have inherited from Group so that you could override the functions. That is the reason for the error message.
Secondly the Real::to_string must return a string at the end. You
might convert the integer using std::to_string.
Last but not least the Group must have a virtual destructor for defined behaviour. Read more here: When to use virtual destructors?
In short, you need
#include <string>
class Group
{
public:
// other code
virtual ~Group() = default;
};
class Real: public Group // --> inherited from base
{
// other codes
public:
std::string to_string() override {
return std::to_string(number);
}
};
As a side, please do not practice with using namespace std;
your class real has no parent. so you cant override to_string()

Pass a function of object of any type to another object in C++

I'm creating a node system (similar to eg. UE4 or Blender's Cycles) in which i can create nodes of different types and use them later. At the moment I have 2 classes of nodes with output functions like these:
class InputInt
{
public:
int output()
{
int x;
std::cin>>x;
return x;
}
};
class RandomInt
{
public:
int rand10()
{
int x;
x = rand()%10;
return x;
}
int rand100()
{
int x;
x = rand()%100;
return x;
}
};
I don't pass anything to these nodes. Now I want to create a node which takes and output function from and object of one of above classes. Here is how I implemented it to use InputInt node only:
class MultiplyBy2
{
typedef int (InputInt::*func)();
func input_func;
InputInt *obj;
public:
MultiplyBy2(InputInt *object, func i): obj(object), input_func(i) {}
int output()
{
return (obj->*input_func)()*2;
}
};
Having this I can create and use object of MultiplyBy2 in main() and it works perfectly.
int main()
{
InputInt input;
MultiplyBy2 multi(&input, input.output);
std::cout<<multi.output()<<std::endl;
}
It doesn't obviously work for object of RandomInt as I have to pass *InputInt object to MultiplyBy2 object. Is there a way to make MultiplyBy2 take any kind of an object with its output function eg. like this?
int main()
{
RandomInt random;
MultiplyBy2 multi2(&random, random.rand10);
std::cout<<multi2.output()<<std::endl;
}
An alternative approach, using a common base class with virtual methods:
#include <iostream>
struct IntOp {
virtual int get() = 0;
};
struct ConstInt: IntOp {
int n;
explicit ConstInt(int n): n(n) { }
virtual int get() override { return n; }
};
struct MultiplyIntInt: IntOp {
IntOp *pArg1, *pArg2;
MultiplyIntInt(IntOp *pArg1, IntOp *pArg2): pArg1(pArg1), pArg2(pArg2) { }
virtual int get() override { return pArg1->get() * pArg2->get(); }
};
int main()
{
ConstInt i3(3), i4(4);
MultiplyIntInt i3muli4(&i3, &i4);
std::cout << i3.get() << " * " << i4.get() << " = " << i3muli4.get() << '\n';
return 0;
}
Output:
3 * 4 = 12
Live Demo on coliru
As I mentioned std::function in post-answer conversation with OP, I fiddled a bit with this idea and got this:
#include <iostream>
#include <functional>
struct MultiplyIntInt {
std::function<int()> op1, op2;
MultiplyIntInt(std::function<int()> op1, std::function<int()> op2): op1(op1), op2(op2) { }
int get() { return op1() * op2(); }
};
int main()
{
auto const3 = []() -> int { return 3; };
auto const4 = []() -> int { return 4; };
auto rand100 = []() -> int { return rand() % 100; };
MultiplyIntInt i3muli4(const3, const4);
MultiplyIntInt i3muli4mulRnd(
[&]() -> int { return i3muli4.get(); }, rand100);
for (int i = 1; i <= 10; ++i) {
std::cout << i << ".: 3 * 4 * rand() = "
<< i3muli4mulRnd.get() << '\n';
}
return 0;
}
Output:
1.: 3 * 4 * rand() = 996
2.: 3 * 4 * rand() = 1032
3.: 3 * 4 * rand() = 924
4.: 3 * 4 * rand() = 180
5.: 3 * 4 * rand() = 1116
6.: 3 * 4 * rand() = 420
7.: 3 * 4 * rand() = 1032
8.: 3 * 4 * rand() = 1104
9.: 3 * 4 * rand() = 588
10.: 3 * 4 * rand() = 252
Live Demo on coliru
With std::function<>, class methods, free-standing functions, and even lambdas can be used in combination. So, there is no base class anymore needed for nodes. Actually, even nodes are not anymore needed (explicitly) (if a free-standing function or lambda is not counted as "node").
I must admit that graphical dataflow programming was subject of my final work in University (though this is a long time ago). I remembered that I distinguished
demand-driven execution vs.
data-driven execution.
Both examples above are demand-driven execution. (The result is requested and "pulls" the arguments.)
So, my last sample is dedicated to show a simplified data-driven execution (in principle):
#include <iostream>
#include <vector>
#include <functional>
struct ConstInt {
int n;
std::vector<std::function<void(int)>> out;
ConstInt(int n): n(n) { eval(); }
void link(std::function<void(int)> in)
{
out.push_back(in); eval();
}
void eval()
{
for (std::function<void(int)> &f : out) f(n);
}
};
struct MultiplyIntInt {
int n1, n2; bool received1, received2;
std::vector<std::function<void(int)>> out;
void set1(int n) { n1 = n; received1 = true; eval(); }
void set2(int n) { n2 = n; received2 = true; eval(); }
void link(std::function<void(int)> in)
{
out.push_back(in); eval();
}
void eval()
{
if (received1 && received2) {
int prod = n1 * n2;
for (std::function<void(int)> &f : out) f(prod);
}
}
};
struct Print {
const char *text;
explicit Print(const char *text): text(text) { }
void set(int n)
{
std::cout << text << n << '\n';
}
};
int main()
{
// setup data flow
Print print("Result: ");
MultiplyIntInt mul;
ConstInt const3(3), const4(4);
// link nodes
const3.link([&mul](int n) { mul.set1(n); });
const4.link([&mul](int n) { mul.set2(n); });
mul.link([&print](int n) { print.set(n); });
// done
return 0;
}
With the dataflow graph image (provided by koman900 – the OP) in mind, the out vectors represent outputs of nodes, where the methods set()/set1()/set2() represent inputs.
Output:
Result: 12
Live Demo on coliru
After connection of graph, the source nodes (const3 and const4) may push new results to their output which may or may not cause following operations to recompute.
For a graphical presentation, the operator classes should provide additionally some kind of infrastructure (e.g. to retrieve a name/type and the available inputs and outputs, and, may be, signals for notification about state changes).
Surely, it is possible to combine both approaches (data-driven and demand-driven execution). (A node in the middle may change its state and requests new input to push new output afterwards.)
You can use templates.
template <typename UnderlyingClass>
class MultiplyBy2
{
typedef int (UnderlyingClass::*func)();
func input_func;
UnderlyingClass *obj;
public:
MultiplyBy2(UnderlyingClass *object, func i) : obj(object), input_func(i) {}
int output()
{
return (obj->*input_func)() * 2;
}
};
int main()
{
// test
InputInt ii;
MultiplyBy2<InputInt> mii{ &ii, &InputInt::output };
RandomInt ri;
MultiplyBy2<RandomInt> mri{ &ri, &RandomInt::rand10 };
}
This is a bit convoluted. However I think you should be making an interface or class that returns a value and the objects should inherit from this. Then the operator class can take any class that inherits from the base/interface. Eg Make an BaseInt class that stores an int and has the output method/ RandomInt and InputInt should inherit from BaseInt

Virtual function don't work

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...

Virtual function is not getting overridden [closed]

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 6 years ago.
Improve this question
I can't figure out why my virtual function is not being overridden, when looking up examples online I can't spot what I'm doing wrong, I must be missing something.
Base Class
class HashTable {
// removed some unrelated functions and data to keep this page short
void Insert(int key, HashTable *htable)
{
int pos = Find(key, htable);
if (htable->table[pos].info != Legitimate)
{
htable->table[pos].info = Legitimate;
int rKey = Reverse(key);
htable->table[pos].element = rKey;
}
}
virtual int Find(int key, HashTable *htable)
{
return 0;
}
};
Children Class
class SingleHash : public HashTable {
int Find(int key, HashTable *htable)
{
int hashVal = HashFunc1(key, htable->size);
while (htable->table[hashVal].info != Empty &&
htable->table[hashVal].element != key)
{
hashVal = hashVal;
hashVal = hashVal % htable->size;
prob = prob + 1;
}
trackProbes(prob);
return hashVal;
}
};
class DoubleHash : public HashTable {
int Find(int key, HashTable *htable)
{
int hashVal = HashFunc1(key, htable->size);
int stepSize = HashFunc2(key, htable->size);
while (htable->table[hashVal].info != Empty &&
htable->table[hashVal].element != key)
{
hashVal = hashVal + stepSize;
hashVal = hashVal % htable->size;
prob = prob + 1;
}
trackProbes(prob);
return hashVal;
}
};
What my main is looking like
int main()
{
int value, size, pos, i = 1;
int choice = 1;
HashTable *htable = new SingleHash;
cin >> value;
htable->Insert(value, htable);
// more unrelated stuff
}
When I run my program it just returns what's in the base class (0) when I make a call to Insert.
There are compile errors in code you provided like functions your not declared public for basics.
I tried to make MCVE for you, and it seems to be working fine.
#include <iostream>
using namespace std;
class HashTable {
public:
void Insert(int x) {
Find(x);
}
virtual int Find(int x) {
cout<<"base hash find \n";
return x; }
};
class SingleHash : public HashTable {
public:
int Find(int x) {
cout<<"single hash find \n";
return x*2;
}
};
class DoubleHash : public HashTable {
public:
int Find(int x) {
cout<<"DOuble hash find \n";
return x*3; }
};
int main(int argc, char** argv)
{
int value;
HashTable *hsingle = new SingleHash;
cin >> value;
hsingle->Insert(value);
HashTable *hdouble = new DoubleHash;
hdouble->Insert(value);
return 0;
}
The output is :
single hash find
DOuble hash find

C++ Destructor is not being called/Object is not being deleted - Potential Memory Leak [closed]

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;
}