I am computing properties of boundary layer flow through a duct. I have a class CChannel which stores geometry of the duct, CFlow which holds global properties of the fluid and CNode which stores local parameters of the boundary layer.
When I execute the program in the current form the first element of the GridPoints vector (variable "alpha") inside CChannel is assigned the same memory location as Uinf which is a private member of the CFlow class. When I change the latter class so that the fields it holds are no longer pointers but regular variables the problem disappears. I also tried reserving memory space for the GridPoints vector inside the class constructor but without any effect. When I was searching for the answer I found that this may have been caused by the in-built code optimiser but didn't manage to learn anything else. (If this is so, how can I get around this without losing efficiency?)I am guessing the problem arises because of the differences between two different memory allocation modes (heap vs stack). I would still like to find out why is this happening exactly so I can store the global flow parameters as pointers and avoid this problem in the future.
Program.cpp
#include <iostream>
#include "Channel.h" // stores the channel geometry
#include "Flow.h" // stores the fluid properties and free stream data
#include "Node.h" // holds the local BL flow properties, e.g. BL thickness, lambda, etc.
using namespace std;
int main(void)
{
int NoNodes=21;
CChannel MyChan(4, 1.2, .8); // L, h1, h2
MyChan.MeshUniform(NoNodes);
CFlow Flow1(.5,1.529e-5,1.19); // Uinf, niu, ro
for (int i=0;i<NoNodes;i++)
{
MyChan.GridPoints->at(i).GetAlpha();
}
return(0);
}
Node.h
#pragma once
class CNode
{
public:
double *alpha, *x, *lambda; // properties dependent on the Pollhausen velocity profile
CNode(void);
~CNode(void);
void GetAlpha(void); // calculates alpha
};
Node.cpp
#include "Node.h"
#include <iostream>
CNode::CNode(void)
{
alpha=new double;
lambda=new double;
*lambda=0;
}
CNode::~CNode(void)
{
delete alpha, x, lambda;
}
void CNode::GetAlpha(void)
{
*alpha=(.3-*lambda/120.);
}
Flow.h
#pragma once
class CFlow
{
private:
double *Uinf, *niu, *ro;
public:
CFlow(double, double, double);
~CFlow(void);
};
Flow.cpp
#include "Flow.h"
CFlow::CFlow(double u, double visc, double den)
{
Uinf=new double;
niu=new double;
ro=new double;
*Uinf=u; // free stream velocity (assumes the inflow is parallel to the channel's CL) [m/s]
*niu=visc; // kinematic viscosity of the fluid [m^2/s]
*ro=den; // density of the fluid [kg/m^3]
}
CFlow::~CFlow(void)
{}
Channel.h
#pragma once
#include <vector>
#include "Node.h"
class CChannel
{
public:
double *L, *h1, *h2; // h1 & h2 defined from the CL => make use of the problem assumed to be symmetric
std::vector<CNode> *GridPoints; // stores data for each individual grid point
CChannel(double, double, double);
~CChannel(void);
void MeshUniform(int); // creates a uniform distribution of nodes along the length of the channel
};
Channel.cpp
#include "Channel.h"
CChannel::CChannel(double length,double height1,double height2)
{
L=new double; // allocate memory
h1=new double;
h2=new double;
GridPoints = new std::vector<CNode>;
*L=length; // assign input values
*h1=height1;
*h2=height2;
}
CChannel::~CChannel(void)
{
delete L, h1, h2, GridPoints; // delete all the members of the class
}
void CChannel::MeshUniform(int NoNodes)
{
GridPoints->resize(NoNodes); // resize the vector
double dx=*L/(NoNodes-1); // increment of length between each pair of nodes
for (int i=0; i<NoNodes; i++)
*GridPoints->at(i).x=0.+i*dx; // assign the location to each node
}
As already described you do not need all these pointers - change them to be raw variable.
If you some day come to the situation where pointers are needed then remember of Rule of Three: What is The Rule of Three?.
You broke this rule by not defining copy constructor and assignment operator in your classes, like in this particular class:
class CNode
{
public:
double *alpha, *lambda; // properties dependent on the Pollhausen velocity profile
CNode(void);
~CNode(void);
void GetAlpha(void); // calculates alpha
};
You are using this CNode in std::vector<CNode> - so there you are suffering from wrong copying of this CNode object.
So you need to add copy constructor and assignment operator - then your problem should disappear even if you will be still using pointers, like in this simple example class:
class Example {
public:
Example() : p(new int()) {}
~Example() { delete p; }
Example(const Example& e) p(new int(e.p?*e.p:0)) {}
Example& operator = (Example e)
{
std::swap(e.p, p);
return *this;
}
private:
int* p;
};
It's compilcated but the explanation is that in your pointer code you haven't written objects that can be copied (as Piotr says you haven't followed the rule of three). Because of this bug what is happening is that memory is begin allocated, memory is being freed and then allocated again. By coincidence when you allocate memory again it reuses the same address that was just freed. That is why you see the same pointer values.
MyChan.GridPoints->at(0).alpha is a pointer but the memory it is pointing at has been freed. Then you allocate some more memory for Flow1.Uinf and it reuses the same freed memory that MyChan.GridPoints->at(0).alpha is pointing at. So you get the same value for both pointers.
One other misunderstanding you have
delete L, h1, h2, GridPoints; // delete all the members of the class
does not delete all members of the class. Only
delete L; // delete all the members of the class
delete h1;
delete h2;
delete GridPoints;
does that. What you wrote deletes GridPoints only. You might want to look up the C++ comma operator for an explanation as to why.
Related
This question already has answers here:
How to resize array in C++?
(5 answers)
Closed 4 years ago.
I am sorry if this has already been covered before. I know how to do this is C and Java but not C++. Without using a pre-existing class which includes the use of Vector, how would you increase the size of an array given the code below?
The array expansion and assignment to the array takes place in push() noted with the all caps comment.
EDIT: As I have mentioned in comments below this is a question regarding manually reallocating arrays rather than using std::vector or "Dynamic Arrays."
Line.h
#include <iostream>
#include "Point.h"
using namespace std;
class Line {
public:
Line();
virtual ~Line();
// TAKE IN NEW POINT, INCREASE THE ARRAY SIZE AND ADD NEW POINT TO THE END OF THE ARRAY
void push(const Point& p);
private:
unsigned int index; // size of "points" array
Point* points;
};
Main.cpp
#include <iostream>
#include "Point.h"
#include "Line.h"
using namespace std;
int main() {
int x, y;
int size; // Some user defined size for the array
Line line;
Point a[size]; // Some points that are already filled
// Push the data in a[] to the variable "line"
for(int i = 0; i < size; i++){
// Increase array size of Point* points in variable line and add a[i] to the end of the array
line.push(points[i]);
}
return 0;
}
The simple answer is you should always use std::vector in this case. However it might be useful to explain just why that is. So lets consider how you would implement this without std::vector so you might see just why you would want to use std::vector:
// Naive approach
Line::push(const Point& p)
{
Point* new_points = new Points[index + 1];
std::copy(std::make_move_iterator(points), std::make_move_iterator(points+index), new_points);
new_points[index] = p;
delete[] points;
points = new_points;
index += 1;
}
This approach has many problems. We are forced to reallocate and move the entire array every time an entry is inserted. However a vector will pre-allocate a reserve and use space out of the reserve for each insert, only re-allocating space once the reserve limit is surpassed. This mean vector will far out perform your code in terms of performance as less time will be spent allocating and moving data unnecessarily. Next is the issue of exceptions, this implementation has no exception guarantees, where as the std::vector provides you with a strong exception guarantee: https://en.wikipedia.org/wiki/Exception_safety. Implementing a strong exception guarantee for your class is none trivial, however you would have automatically got this had you implemented this in terms of std::vector as such
Line::push(const Point& p)
{
points.push_back(p);
}
There are also other more subtle problems with your approach, your class does not define copy or assignment operators and so gets compiler generated shallow copy versions generated which means if someone copies your class then allocated members will get deleted twice. To resolve this you need to follow the rule of 3 paradigm pre C++11 and the rule of 5 for C++ 11 onwards: https://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming). However had you used a vector none of this would be needed as you would benefit from the rule of zero and be able to rely on the compiler generated defaults: https://blog.rmf.io/cxx11/rule-of-zero
Essentially the only way is to use a dynamic array (one created using new[]) and to create an entirely new dynamic array and copy (or move) the objects from the old array to the new one.
Something like this:
class Line {
public:
Line(): index(0), points(nullptr) {} // initialize
virtual ~Line() { delete[] points; } // Clean up!
void push(const Point& p)
{
// create new array one element larger than before
auto new_points = new Point[index + 1];
// copy old elements to new array (if any)
for(unsigned int p = 0; p < index; ++p)
new_points[p] = points[p];
new_points[index] = p; // then add our new Point to the end
++index; // increase the recorded number of elements
delete[] points; // out with the old
points = new_points; // in with the new
}
private:
unsigned int index; // size of "points" array
Point* points;
};
But this approach is very inefficient. To do this well is quite complex. The main problems with doing things this way are:
Exception safety - avoiding a memory leak if an exception is thrown.
Allocation - avoiding having to reallocate (and re-copy) every single time.
Move semantics - taking advantage of some objects ability to be moved much more efficiently than they are copied.
A (slightly) better version:
class Line {
public:
Line(): index(0) {} // initialize
virtual ~Line() { } // No need to clean up because of `std::unique_ptr`
void push(const Point& p)
{
// create new array one element larger than before
auto new_points = std::unique_ptr<Point[]>(new Point[index + 1]);
// first add our new Point to the end (in case of an exception)
new_points[index] = p;
// then copy/move old elements to new array (if any)
for(unsigned int p = 0; p < index; ++p)
new_points[p] = std::move(points[p]); // try to move else copy
++index; // increase the recorded number of elements
std::swap(points, new_points); // swap the pointers
}
private:
unsigned int index; // size of "points" array
std::unique_ptr<Point[]> points; // Exception safer
};
That takes care of exception safety and (to some degree - but not entirely) move semantics. However it must be pointed out that exception safety is only going to be complete if the elements stored in the array (type Point) are themselves exception safe when being copied or moved.
But this does not deal with efficient allocation. A std::vector will over allocate so it doesn't have to do it with every new element. This code also misses a few other tricks that a std::vector would employ (like allocating uninitialized memory and constructing/destructing the elements manually as and when they are needed/discarded).
You basically have no way but to allocate a new array, copy existing values inside and delete [] the old one. That's why vector is doing the reallocation by a multiplicative factor (say each reallocation doubles the size). This is one of the reasons you want to use the standard library structures instead of reimplementing.
Keep It Simple
In my opinion, in this case, it's better to use a Linked-List of CPoint in CLine:
struct CPoint
{
int x = 0, y = 0;
CPoint * m_next = nullptr;
};
class CLine
{
public:
CLine() {};
virtual ~CLine()
{
// Free Linked-List:
while (m_points != nullptr) {
m_current = m_points->m_next;
delete m_points;
m_points = m_current;
}
};
// TAKE IN NEW POINT, INCREASE THE ARRAY SIZE AND ADD NEW POINT TO THE END OF THE ARRAY
void push(const CPoint& p)
{
m_current = (((m_points == nullptr) ? (m_points) : (m_current->m_next)) = new CPoint);
m_current->m_x = p.m_x;
m_current->m_y = p.m_y;
m_index++;
};
private:
unsigned int m_index = 0; // size of "points" array
CPoint * m_points = nullptr, * m_current = nullptr;
};
.
Or, even better with smart pointers:
#include <memory>
struct CPoint
{
int m_x = 0, m_y = 0;
std::shared_ptr<CPoint> m_next;
};
class CLine
{
public:
CLine() {};
virtual ~CLine() {}
// TAKE IN NEW POINT, INCREASE THE ARRAY SIZE AND ADD NEW POINT TO THE END OF THE ARRAY
void push(const CPoint& p)
{
m_current = (((m_points == nullptr) ? (m_points) : (m_current->m_next)) = std::make_shared<CPoint>());
m_current->m_x = p.m_x;
m_current->m_y = p.m_y;
m_index++;
};
private:
unsigned int m_index = 0; // size of "points" array
std::shared_ptr<CPoint> m_points, m_current;
};
Having a struct such as:
struct PAIR {
vector<double> a;
vector<double> b;
};
Is using a function like the following a proper way to release the memory after defining and populating such a struct? If not, how do you deal with this situation?
void release(PAIR& p){
vector<double>().swap(p.a);
vector<double>().swap(p.b);
}
Isn't there a way to call some predefined/std function on PAIR itself to release memory?
Note that I'm not using new, etc. so definitions are simply like PAIR p;. Also, the struct is much more complex than just a pair of vectors that could have been defined using a std::pair.
All the related questions in SO on releasing memory for vectors are either about vectors themselves or vectors of a struct, not a struct containing multiple vectors. I'm looking for an elegant way to release memory used by such a struct.
Context
The vectors get really big, and I want to release the memory as soon as I can. But that lifetime/usability reaches in the middle of function! I don't want to spread the functionality in this function to multiple functions. These are pretty complicated computations and don't want to mess things up.
Given function does not release memory on the stack actually. It is approximately equivalent to
p.a.clear();
p.a.shrink_to_fit();
The vector itself remains in the memory (just with 0 elements).
Remember, any memory that was allocated on the stack (~ without the use of new) gets released only when the variable occupying this memory goes out of scope, not earlier.
So if you have a variable on the stack and want to delete it, you can just limit its scope:
struct PAIR {
vector<double> a;
vector<double> b;
};
int main()
{
// some stuff before...
{
PAIR p;
// some stuff with p object...
} // here p gets deleted (all memory gets released)
// some stuff after...
}
You mentioned new PAIR. With pointers it would look like this:
int main()
{
// some stuff before...
PAIR* p = new PAIR;
// some stuff with p object...
delete p; // here p gets deleted (all memory gets released)
// some stuff after...
}
Or as commentators requested:
int main()
{
// some stuff before...
{
auto p = std::make_unique<PAIR>();
// some stuff with p...
} // here p gets deleted (all memory gets released)
// some stuff after...
}
Is that what you wanted to achieve?
Does PAIR have to be a POD? Maybe something like this might work for you?
struct PAIR
{
private:
std::unique_ptr<std::vector<double>> aptr;
std::unique_ptr<std::vector<double>> bptr;
PAIR(const PAIR&) = delete;
public:
PAIR() : aptr(std::make_unique<std::vector<double>()),
bptr(std::make_unique<std::vector<double>()) {}
~PAIR() { release(); }
std::vector<double> &a = *aptr;
std::vector<double> &b = *bptr;
void release()
{
aptr.reset();
bptr.reset();
}
...
};
simply .resize(0) the vectors.
I have a question regarding how to correctly delete structs and it's respective pointers declared inside.
I have extracted an example from a project i have running and it doesn't seem to work correctly, the code doesn't crash but it seems i have some "memory leaks". I'm not sure that is the right wording. The issue is that the values is not really reset and are kept in the memory next time i initiate a class.
Sudocode below:
Header:
ProgramHeader.h
class ClassA : public publicClassA
{
public:
ClassA(void);
virtual ~ClassA();
private:
struct ApStruct{
struct
{
float *refA[2];
float *refB[2];
float *pVarA;
} fR;
struct
{
float *refA[2];
float *refB[2];
float *pVarA;
} f1kHz;
};
ApStruct* GetApStruct;
}
Program:
Program.cpp
#include "ProgramHeader.h"
ClassA::~ClassA()
{
//EDIT i did a typo my looks like this:
//delete ApStruct; //Wrong code
delete GetApStruct; //Corrected - however still not working
}
main()
{
GetApStruct = new ApStruct();
//Do Code
}
Hope it all makes a bit sense,
EDIT:
I have updated one wrong line in the code - however the question still remains the same. I will have a look at below to understand before i implement a solution.
EDIT 24/10/2015
I have been trying out a few of the suggestions below and im not able to find a solution to my issue, i must admit i also have difficulties to narrow it down what could cause it.
My code is part of a DLL. The code wraps some source code im not in control of, and therefore i have limited options how i init using constructors and new on pointers.
The reason i still think i have memory leak issues is if i add a "magic float" in my code the output of my functions change, even the float is not used anywhere - it is just declared.
I get different results when:
Calling InitCode - once!
then i will call CallCode multiple time - doing my calculations
Destruct the instance of the class
When i repeat the above again i get different result from the first time i run the code but afterwards it stays the same.
If i include the magic line all seems to work???
Updated SudoCode:
Program.cpp
#include "ProgramHeader.h"
ClassA::~ClassA()
{
//EDIT i did a typo my looks like this:
//delete ApStruct; //Wrong code
delete GetApStruct; //Corrected - however still not working
}
main()
{
void initCode()
{
GetApStruct = new ApStruct();
float InitValue = 0.F
//Magic line:
float magicLine = 123456.f; //If this line is commented out i get different results in my code
//End Magic Line
fr.refA[0] = &InitValue;
fr.refA[0] = &InitValue;
fr.refA[0] = &InitValue;
fr.pVarA = &InitValue;
...
}
void CallCode()
{
float CallValue = 123.F
//Magic line:
float magicLine = 123456.f; //If this line is commented out i get different results in my code
//End Magic Line
fr.refA[0] = &CallValue;
fr.refA[0] = &CallValue;
fr.refA[0] = &CallValue;
fr.pVarA = &CallValue;
...
}
}
Thanks guys for you support,
Thomas
I would recommend something like the following for allocation and cleanup...
#include <iostream>
using namespace std;
class ClassA
{
public:
ClassA(void);
virtual ~ClassA();
private:
struct ApStruct {
struct
{
float *refA[2];
float *refB[2];
float *pVarA;
} fR;
struct
{
float *refA[2];
float *refB[2];
float *pVarA;
} f1kHz;
};
ApStruct* GetApStruct;
};
ClassA::ClassA(void) {
GetApStruct = new ApStruct{};
GetApStruct->fR.refA[0] = new float{ 1.f };
GetApStruct->fR.refA[1] = new float{ 2.f };
GetApStruct->fR.refB[0] = new float{ 3.f };
GetApStruct->fR.refB[1] = new float{ 4.f };
GetApStruct->fR.pVarA = new float { 0.f };
// do same for struct f1kHz
// ...
cout << "Construction" << endl;
}
ClassA::~ClassA()
{
if (GetApStruct != nullptr) {
if (GetApStruct->fR.refA[0] != nullptr) {
delete GetApStruct->fR.refA[0];
GetApStruct->fR.refA[0] = nullptr;
}
if (GetApStruct->fR.refA[1] != nullptr) {
delete GetApStruct->fR.refA[1];
GetApStruct->fR.refA[1] = nullptr;
}
if (GetApStruct->fR.refB[0] != nullptr) {
delete GetApStruct->fR.refB[0];
GetApStruct->fR.refB[0] = nullptr;
}
if (GetApStruct->fR.refB[1] != nullptr) {
delete GetApStruct->fR.refB[1];
GetApStruct->fR.refB[1] = nullptr;
}
if (GetApStruct->fR.pVarA != nullptr) {
delete GetApStruct->fR.pVarA;
GetApStruct->fR.pVarA = nullptr;
}
// do same for struct f1kHz
// ...
// finally
delete GetApStruct;
GetApStruct = nullptr;
}
cout << "Destruction" << endl;
}
int main() {
{
ClassA a;
}
system("pause");
return 0;
}
Well when you create a structure/class object, it holds the variables and pointers in that object memory area( say an object occupies some space in memory. Let's call it a box). Those pointer variables when initialized with new() or malloc(), are given space outside of that box in which the object's data resides. Those pointers now point to some memory area that is outside of that object's memory area. Now when the object is destructed, that space occupied by object (as we called it the box) is destroyed accompanying the pointer variables. The memory area pointed by the pointers is still in there in program/process memory area. Now we have no clue what's it address or where it lies. That's called memory leak. To avoid this situation, we need to de-allocate the memory referenced by pointers using delete keyword. We're free to go now. I tried to illustrate it with a simple graphic below. ObjectA box illustrates the area occupied by it in the memory. Note that this container/box holds the local varialbes including pointer. The pointer points to some memory location, say 0xFFF... and is illustrated by green line. When we destroy ObjectA, It simply destroys everything in it including 0xFFF address. But the memory located on 0xFFF is still allocated in the memory. A memory leak.
In your destructor, de-allocate memory explicitly using delete keyword. Whoa! We saved the memory.
From Wikipedia Resource Acquisition Is Initialization
Resource Acquisition Is Initialization (RAII) is a programming idiom used prominently in C++. In RAII, resource acquisition is done during object creation, by the constructor, while resource release is done during object destruction, by the destructor. If objects are destroyed properly, resource leaks do not occur.
So you can new the memory used for pointers in constructor and release them in destructor:
ClassA::ClassA(void) {
GetApStruct = new ApStruct;
GetApStruct->fR.refA[0] = new float{ 1.f };
GetApStruct->fR.refA[1] = new float{ 2.f };
}
ClassA::~ClassA(void) {
delete []GetApStruct->fR.refA;
delete GetApStruct;
}
Alright, let me be direct:
If you are using new or delete, you are doing it wrong.
Unless you are an experienced user, or you wish to implement a low-level side project, do not ever use new and delete.
Instead, use the existing standard classes to handle memory ownership, and just avoid heap-allocation when it is unnecessary. As a bonus, not only will you avoid memory leaks, but you will also avoid dangling references (ie, using memory after deleting it).
class ClassA : public publicClassA {
public:
private:
struct ApStruct{
struct
{
float refA[2];
float refB[2];
float pVarA;
} fR;
struct
{
float refA[2];
float refB[2];
float pVarA;
} f1kHz;
};
ApStruct GetApStruct;
}
And yes, in your case it is as simple as removing the pointers. Otherwise, if you want dynamic arrays (ie, arrays whose length is unknown at compile-time) use std::vector.
I need to save objects as pointers in dynamic array but i have problem.
This is my code, there are three classes and i need to have array (arrayoftwo) of poiters to class Two that would work further with class Three and so on. I have two problems. One is that i cant figure out how to dynamically allocate space for my arrayoftwo (which i need to dynamically resize by number of stored pointers) and second problem is how to exactly store pointers to objects without destroying object itself.
Here is my code:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
class One {
public:
bool addTwo(int a);
private:
void getspace(void);
class Two {
public:
int a;
private:
class Three {
/*...*/
};
Three arrayofThree[];
};
int freeindex;
int allocated;
Two *arrayoftwo[];
};
void One::getspace(void){
// how to allocate space for array of pointers ?
arrayoftwo=new *Two[100];
allocated=100;
}
bool One::addTwo(int a){
Two temp;
temp.a=a;
getspace();
arrayoftwo[freeindex]=&temp;
freeindex++;
return true;
//after leaving this method, will the object temp still exist or pointer stored in array would be pointing on nothing ?
}
int main() {
bool status;
One x;
status = x . addTwo(100);
return 0;
}
Thank you for any help.
EDIT: I cant use vector or any other advanced containers
temp will not exist after leaving addTwo; the pointer you store to it is invalid at that point. Instead of storing the object as a local variable, allocate it on the heap with new:
Two* temp = new Two();
To allocate an array of pointers:
Two** arrayoftwo; // declare it like this
// ...
arrayoftwo = new Two*[100];
And getspace should either be passed a (from addTwo) or a should be stored as the member variable allocated and getspace should access it from there. Otherwise it's assuming 100.
I have a program that creates a random amount of points interspersed throughout the program. While it runs, I would also like to create an object for each point and store it in a vector. I have created a Point class with various attributes but I have no idea on how to implement the above. When looking at other questions that deal with similar, yet nonidentical problems, pointers are used, but again, I have no idea on how to implement them.
Im not quite sure what you really want to achieve, but i hope this will help you though.
To create an object dynmically use the new operator. The new operator always returns a pointer:
Point* pointObj = new Point();
If you have specified a constructor the call is very similar to normal construction on stack:
Point* pointObj = new Point(x,y);
A std::vector stores objects at runtime (dynamically in the heap), but instead of creating them by it own it simply copies them:
std::vector<Point> vec; //if this object is destructed it contents are destructed aswell
Point pointObj(x,y); //point on stack; will get destructed if it gets out of scope
vec.push_back(pointObj) //copy pointObj to a dynamic location on the heap
Well, I don't know what parameters your Point constructor takes, but your description sounds as if you want to do something like this:
std::vector<Point> MyGlobalPointList;
and inside your program you have a few of these:
MyGlobalPointList.push_back(Point(x,y,color));
Are you looking for automatic object management tied with object creation here? If so, AbstractFactory can help you here. Apart from the factory being THE mechanism for constructing objects (Points) instead of doing so everywhere yourself, it can also carry out object management e.g. managing them in a vector.
class Point {
friend class PointFactory;
Point(int _x, int _y) : x(_x), y(_y) { }
private:
~Point(); //destructor is private
int x, y;
}
class PointFactory {
public:
Point* createPoint() { //Creates random point
return createPoint(rand(), rand());
}
Point* createPoint(int x, int y) { //Creates specified point
Point* p = new Point(x, y);
points.push_back(p);
return p;
}
void deletePoint(Point *p) { //p not in use anymore
std::vector<Point*>::iterator it = std::find(objects.begin(), objects.end(), p);
if (it != objects.end()) {
objects.erase(it);
}
delete p;
}
private:
std::vector<Point*> objects;
}
int main(...) {
Point *p = pointFactory.createPoint(); //instead of new Point()
//use p
pointFactory.deletePoint(p); //p not in use anymore
return 0;
}
Hope this is what you are looking for.
Ankur Satle