Dynamically allocated object producer - c++

Look at this class:
//HPP
class A {
public:
A();
~A();
B *fetchNew();
private:
B *currentValue;
}
//CPP
A::A() {}
A::~A {
delete currentValue;
}
B *A::fetchNew() {
delete currentValue;
currentValue = new B();
//apply magic to currentValue
return currentValue;
}
This class holds a pointer to instance of class B. Every time fetchNew() is called, the old one gets deleted, a new one is allocated and magic is applied to it, after what new and shiny currentValue is returned.
This method is called very frequently (in real life, it's a method that returns a view matrix in a game's main loop, so it's called once every frame, about 60 times a second).
Once the A object gets deleted, it deletes the current currentValue, which would otherwise leak.
Is there a prettier way to achieve this?
EDIT:
Here's the actual code, since it has a twist (just the fetchNow() method):
glm::mat4x4 *Camera::getViewMatrix() {
//transformation <<-apply shiny and fancy magic;
delete viewMatrix;
viewMatrix = new glm::mat4x4();
*viewMatrix *= glm::mat4_cast(transformation->getRotation());
*viewMatrix = glm::translate(*viewMatrix, transformation->getPosition());
return viewMatrix;
}

Is there a prettier way to achieve this?
I would recommend rather to use a std::unique_ptr<B> than a raw pointer B*:
//HPP
#include <memory>
class A {
public:
A();
~A();
std::unique_pty<B> fetchNew();
private:
// You don't need that: B *currentValue;
}
//CPP
A::A() {}
A::~A {
// You don't need that: delete currentValue;
}
std::unique_ptr<B> A::fetchNew() {
// You don't need that: delete currentValue;
std::unique_ptr<B> newValue = std::make_unique<B>();
// apply magic to newValue and dereference using * or -> as with any raw pointer
return newValue;
}
This approach has several advantages:
You don't have to care about deletion or memory leaks in A
The transfer of ownership for the result of fetchNew() is semantically clear
It's a more clear API, the client will know they get ownership of the pointer and do not have to riddle if they need to delete that instance or not
You give the client the flexibility to determine the lifetime scope of the B instance themselves.
As for your edited addition it should look like:
std::unique_ptr<glm::mat4x4> Camera::getViewMatrix() {
//transformation <<-apply shiny and fancy magic;
std::unique_ptr<glm::mat4x4> viewMatrix = std::make_unique<glm::mat4x4>();
*viewMatrix *= glm::mat4_cast(transformation->getRotation());
*viewMatrix = glm::translate(*viewMatrix, transformation->getPosition());
return viewMatrix;
}

Related

Use constructor to allocate memory

I have a class that contains several arrays whose sizes can be determined by parameters to its constructor. My problem is that instances of this class have sizes that can't be determined at compile time, and I don't know how to tell a new method at run time how big I need my object to be. Each object will be of a fixed size, but different instances may be different sizes.
There are several ways around the problem:- use a factory- use a placement constructor- allocate arrays in the constructor and store pointers to them in my object.
I am adapting some legacy code from an old application written in C. In the original code, the program figures out how much memory will be needed for the entire object, calls malloc() for that amount, and proceeds to initialize the various fields.
For the C++ version, I'd like to be able to make a (fairly) normal constructor for my object. It will be a descendant of a parent class, and some of the code will be depending on polymorphism to call the right method. Other classes descended from the same parent have sizes known at compile time, and thus present no problem.
I'd like to avoid some of the special considerations necessary when using placement new, and I'd like to be able to delete the objects in a normal way.
I'd like to avoid carrying pointers within the body of my object, partially to avoid ownership problems associated with copying the object, and partially because I would like to re-use as much of the existing C code as possible. If ownership were the only issue, I could probably just use shared pointers and not worry.
Here's a very trimmed-down version of the C code that creates the objects:
typedef struct
{
int controls;
int coords;
} myobject;
myobject* create_obj(int controls, int coords)
{
size_t size = sizeof(myobject) + (controls + coords*2) * sizeof(double);
char* mem = malloc(size);
myobject* p = (myobject *) mem;
p->controls = controls;
p->coords = coords;
return p;
}
The arrays within the object maintain a fixed size of the life of the object. In the code above, memory following the structure of myobject will be used to hold the array elements.
I feel like I may be missing something obvious. Is there some way that I don't know about to write a (fairly) normal constructor in C++ but be able to tell it how much memory the object will require at run time, without resorting to a "placement new" scenario?
How about a pragmatic approach: keep the structure as is (if compatibility with C is important) and wrap it into a c++ class?
typedef struct
{
int controls;
int coords;
} myobject;
myobject* create_obj(int controls, int coords);
void dispose_obj(myobject* obj);
class MyObject
{
public:
MyObject(int controls, int coords) {_data = create_obj(controls, coords);}
~MyObject() {dispose_obj(_data);}
const myobject* data() const
{
return _data;
}
myobject* data()
{
return _data;
}
int controls() const {return _data->controls;}
int coords() const {return _data->coords;}
double* array() { return (double*)(_data+1); }
private:
myobject* _data;
}
While I understand the desire to limit the changes to the existing C code, it would be better to do it correctly now rather than fight with bugs in the future. I suggest the following structure and changes to your code to deal with it (which I suspect would mostly be pulling out code that calculates offsets).
struct spots
{
double x;
double y;
};
struct myobject
{
std::vector<double> m_controls;
std::vector<spots> m_coordinates;
myobject( int controls, int coordinates ) :
m_controls( controls ),
m_coordinates( coordinates )
{ }
};
To maintain the semantics of the original code, where the struct and array are in a single contigious block of memory, you can simply replace malloc(size) with new char[size] instead:
myobject* create_obj(int controls, int coords)
{
size_t size = sizeof(myobject) + (controls + coords*2) * sizeof(double);
char* mem = new char[size];
myobject* p = new(mem) myobject;
p->controls = controls;
p->coords = coords;
return p;
}
You will have to use a type-cast when freeing the memory with delete[], though:
myobject *p = create_obj(...);
...
p->~myobject();
delete[] (char*) p;
In this case, I would suggest wrapping that logic in another function:
void free_obj(myobject *p)
{
p->~myobject();
delete[] (char*) p;
}
myobject *p = create_obj(...);
...
free_obj(p);
That being said, if you are allowed to, it would be better to re-write the code to follow C++ semantics instead, eg:
struct myobject
{
int controls;
int coords;
std::vector<double> values;
myobject(int acontrols, int acoords) :
controls(acontrols),
coords(acoords),
values(acontrols + acoords*2)
{
}
};
And then you can do this:
std::unique_ptr<myobject> p = std::make_unique<myobject>(...); // C++14
...
std::unique_ptr<myobject> p(new myobject(...)); // C++11
...
std::auto_ptr<myobject> p(new myobject(...)); // pre C++11
...
New Answer (given comment from OP):
Allocate a std::vector<byte> of the correct size. The array allocated to back the vector will be contiguous memory. This vector size can be calculated and the vector will manage your memory correctly. You will still need to be very careful about how you manage your access to that byte array obviously, but you can use iterators and the like at least (if you want).
By the way here is a little template thing I use to move along byte blobs with a little more grace (note this has aliasing issues as pointed out by Sergey in the comments below, I'm leaving it here because it seems to be a good example of what not to do... :-) ) :
template<typename T>
T readFromBuf(byte*& ptr) {
T * const p = reinterpret_cast<T*>(ptr);
ptr += sizeof(T);
return *p;
}
Old Answer:
As the comments suggest, you can easily use a std::vector to do what you want. Also I would like to make another suggestion.
size_t size = sizeof(myobject) + (controls + coords*2) * sizeof(double);
The above line of code suggests to me that you have some "hidden structure" in your code. Your myobject struct has two int values from which you are calculating the size of what you actually need. What you actually need is this:
struct ControlCoord {
double control;
std::pair<double, double> coordinate;
};
std::vector<ControlCoord>> controlCoords;
When the comments finally scheded some light on the actual requirements, the solution would be following:
allocate a buffer large enough to hold your object and the array
use placement new in the beginning of the buffer
Here is how:
class myobject {
myobject(int controls, int coords) : controls(controls), coords(coords) {}
~myobject() {};
public:
const int controls;
const int coords;
static myobject* create(int controls, int coords) {
std::unique_ptr<char> buffer = new char[sizeof(myobject) + (controls + coords*2) * sizeof(double)];
myobject obj* = new (buffer.get()) myobject(controls, coords);
buffer.release();
return obj;
}
void dispose() {
~myobject();
char* p = (char*)this;
delete[] p;
}
};
myobject *p = myobject::create(...);
...
p->dispose();
(or suitably wrapped inside deleter for smart pointer)

c++ correct deletion of structs and pointers

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.

How to delete an object without having access to it?

I know that whenever I create a new object for a class, that object is stored in memory. I also know that in creating that object, it can only be accessed within the set of braces it is created in (Scope visibility). I need to find a way to delete that object outside of the braces it is created in. I have looked at smart pointers briefly, and it might be what I want to use? I'm assuming it is, I just don't know for sure. If a smart pointer can satisfy my needs, would someone please provide me with an example of how to use a smart pointer to access an object outside of where it has been created? Thanks :)
EDIT:
Example of what I'm trying to do:
class ModernWarfare2
{
//my class
ModernWarfare2();
};
DWORD XamHook(DWORD r3, DWORD r4, DWORD r5)
{
switch(XamGetCurrentTitleId())//a function that tells what game is being played
{
case Xbox360Dashboard://if i were to exit the game mw2
{
if(CODAllocated)//a boolean
{
//free the memory of the previous cod game
if(MW2Allocated)//another boolean
{
delete[] MW2;//gives me an error because i dont have access to MW2
}
}
break;
}
case COD_MW2:
{
if(!CODAllocated)
{
if(!MW2Allocated)
{
ModernWarfare2 *MW2 = new ModernWarfare2();
}
}
break;
}
}
return XamInputGetState(r3,r4,r5);
}
How do I fix my issue?
I also know that in creating that object, the object can only be accessed within the set of braces it is created in.
Not necessarily; that's only true when you construct objects with automatic storage duration, like this:
void foo()
{
T obj;
}
Such objects, yes, go out of scope.
Objects you allocate dynamically do not:
void foo()
{
T* obj = new T();
}
This is a memory leak because you never destroy *obj; however, you can access it from pretty much wherever you like:
T* foo()
{
return new T();
}
void bar()
{
T* obj = foo();
// yay!
}
or:
T* obj = nullptr;
void foo()
{
obj = new T();
}
void bar()
{
// do stuff with *obj
}
void baz()
{
foo();
bar();
}
This all gets dangerous and messy because you end up with spaghetti code in which the lifetime of the dynamically-allocated object is unclear, and in the examples above I still haven't approached the topic of eventually destroying the object. You have to be really careful not to destroy it whilst you're still using it.
This is where smart pointers come in, but if you want a tutorial on using smart pointers I'm going to have to refer you back to your C++11 book.
"I also know that in creating that object, the object can only be accessed within the set of braces it is created in." - This depends on how you create the object.
Example 1 (can't be accessed outside braces):
void func(void)
{
Object obj("foo", "bar");
}
Example 2 (can be accessed outside braces):
Object* func(void)
{
Object* obj = new Object("foo", "bar");
return obj;
}
Example 2 can be deleted using the keyword delete.
Take a look here for more information on pointers.
I haven't personally found a use for smart pointers but MSDN has good information on the topic here
By creating MW2 with
{
ModernWarfare2 *MW2 = new ModernWarfare2();
}
I was not able to reference MW2 elsewhere. By doing this, I can create it and delete it in two different spots:
class ModernWarfare2
{
//my class
ModernWarfare2();
};
ModernWarfare2 *MW2 = NULL;
DWORD XamHook(DWORD r3, DWORD r4, DWORD r5)
{
switch(XamGetCurrentTitleId())//a function that tells what game is being played
{
case Xbox360Dashboard://if i were to exit the game mw2
{
if(CODAllocated)//a boolean
{
//free the memory of the previous cod game
if(MW2Allocated)//another boolean
{
delete MW2;//gives me an error because i dont have access to MW2
}
}
break;
}
case COD_MW2:
{
if(!CODAllocated)
{
if(!MW2Allocated)
{
if(MW2 == NULL)
{
MW2 = new ModernWarfare2();
}
}
}
break;
}
}
return XamInputGetState(r3,r4,r5);
}
I think what you need is basic design pattern
Make the data and the functions members of a class
class SomeHandler
{
public:
void Acquire( /* some source */ );
void DoSomething( /* eventual parameters */ );
bool TrySomething(); // returns true if successful
private:
void internalFunction();
bool inGoodState;
SomeType dataINeed;
SomeOtherType otherData;
};
void SomeHandler::Acquire( /**/ )
{
// implement like this
}
now the functions can access the all the data
the use it like
int main()
{
SomeHandler h;
h.Acquire();
if( h.TrySomething() )
{
h.DoSomething();
}
}
Based on your code snippet, You have to save your pointer MW2 for
future so that you can delete the pointer.
I would suggest you to change
if(!MW2Allocated)
to
if(!MW2)
so that you don't have to create another variable for saving the reference to your allocated memory
Offcourse you have to move
ModernWarfare2 *MW2
to a larger scope (move it to the scope same as MW2Allocated) and initialize it to NULL.
Use "nullptr" instead of "NULL" if you are using C++11 supported compiler.
Also makesure you use
delete
instead of
delete[]
since this is not an array allocation
I don't think you can use smart pointers to skip saving your reference to the allocated memory,
since they are meant to make the memory deletion automatic or to make sure two deletion doesn't occur
for the same memory.
Refer to
http://www.codeproject.com/Articles/541067/Cplusplus-Smart-Pointers
for a good explanation about smart pointers

Correct memory management for struct

I want to be sure that no memory leak takes place.
struct tStruct{
uint32_t id;
A* a;
C b;
};
std::vector<tStruct*> m_vector;
I push and erase objects into vector following way.
Pushing :
tStruct* myStruct = new tStruct;
myStruct->id = ID; // Some unique value
myStruct->a= new A();
myStruct->b = c; // c is an object
m_vector.push_back(myStruct);
Erasing :
// Some stuff here
for (uint32_t i = 0; i < m_vector.size(); i++) {
if (m_vector.at(i)->id == ID) { // Some filtering
delete m_vector.at(i);
m_vector.erase(m_vector.begin() + i);
}
}
Do i understand correctly that
I need to delete myStruct->a explicitely as it is alloced in heap ?
For the other members, they will be deleted automatically as they are in stack.
Rule of thumb: If you have a new you must have a corresponding delete. Same with malloc and free in C.
You need to manually delete all dynamically allocated objects which are created by new operator. Otherwise you have potential memory leak, as you haven't deleted A* a;
new and delete, new [] and delete [] should always be used in pair.
Better solution is to use smart pointers:
struct tStruct
{
uint32_t id;
std::unique_ptr<A> a;
C b;
};
std::vector<std::unique_ptr<tStruct>> m_vector;
Use erase remove idiom to remove items from vector:
m_vector.erase(std::remove_if(m_vector.begin(), m_vector.end(),
[](std::unique_ptr<tStruct>& up){ return up->id == ID; }),
m_vector.end());
Everytime you create an object in the heap using new, there must be a corresponding delete somewhere. Otherwise you will be leaking resources (memory, in this case).
But, generally speaking (and this applies to your example), the best that you can do is using an auxiliary class to manage those resources. In your case, a smart pointer. In C++11 the standard library offers std::shared_ptr<> which looks like the right smart pointer for your case:
struct tStruct{
uint32_t id;
std::shared_ptr<A> a;
C b;
};
std::vector<std::shared_ptr<tStruct>> m_vector;
Creating a smart pointer is not too different from creating a raw pointer:
std::shared_ptr<tStruct> myStruct (new tStruct);
myStruct->id = ID; // Some unique value
myStruct->a.reset(new A());
myStruct->b = c; // c is an object
m_vector.push_back(myStruct);
But now you can forget about calling delete because std::shared_ptr<> will take care of that:
// Some stuff here
for (uint32_t i = 0; i < m_vector.size(); i++) {
if (m_vector.at(i)->id == ID) { // Some filtering
// delete m_vector.at(i); This is no longer needed
m_vector.erase(m_vector.begin() + i);
}
}
Your code still contains several memory leaks. Your pushing code does not have any roll-back for if pushing the object fails:
tStruct* myStruct = new tStruct;
myStruct->id = ID;
myStruct->a= new A(); //could throw, if it does, then `myStruct` will leak
myStruct->b = c; // c is an object
//could throw, if it does, then `myStruct` and `myStruct->a` will leak
m_vector.push_back(myStruct);
In general, any manual calls to delete indicates that your code either leaks or is overly complicated. To make the code not leak, you should use smart pointers:
struct tStruct{
uint32_t id;
std::unique_ptr<A> a;
C b;
};
std::vector<std::unique_ptr<tStruct>> m_vector;
To construct:
std::unique_ptr<tStruct> myStruct(new tStruct);
myStruct->id = ID;
myStruct->a.reset(new A());
myStruct->b = c; // c is an object
m_vector.push_back(std::move(myStruct));
No special deletion code is needed.

Creating Dynamic Objects With No User Input

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