initialize array in constructor - c++

I want to have a class which has a member array. The size of the array should be given when I initialize the object. I just found a way with pointers to do this. I think it is working correctly, but can you maybe tell me if this is the best way to do it or if there are any things which do not work which I haven't recognized yet?
#include <iostream>
using namespace std;
class Surface {
private:
float dx;
int N;
float* mesh_points;
public:
Surface(float, int);
~Surface();
void set_dx (float);
float get_dx();
};
Surface::Surface(float dx,int N){
this->dx = dx;
this ->N = N;
mesh_points = new float[N];
}
void Surface::set_dx (float dx) {
this->dx = dx;
}
float Surface::get_dx (void) {
return dx;
}
Surface::~Surface(){
delete[] mesh_points;
}
int main () {
Surface s(1.2,10);
s.set_dx (3.3);
cout << "dx: "<< s.get_dx() <<endl;
float mesh_points[3];
return 0;
}

can you maybe tell me if this is the best way to do it or if there are any things which do not work which I haven't recognized yet?
That'd be my take basing on existing best practices:
class Surface {
private:
std::vector<float> mesh_points;
public:
float dx;
Surface(float dx, std::size_t n);
};
Surface::Surface(float dx, std::size_t n)
: dx(dx)
, mesh_points(n)
{
}
In short, the changes made:
Got rid of manual memory management, which implies dtor as well.
Added names for parameters in declarations (really important for usability/IDEs, don't remove them!)
Got rid of superfluous accessors and made dx public.
Used ctor init lists, making the body obsolete.
Got rid of using namespace std; in lieu of explicit std:: prefix.
Changed n type to std::size_t (see comment).
Please note that the current interface doesn't allow any access to mesh_points.

Here's an alternative suggestion that allows you to keep your current implementation but is a lot safer.
class Surface {
private:
float dx;
int N;
float* mesh_points;
public:
Surface(float, int);
~Surface();
void set_dx (float);
float get_dx();
Surface(const Surface&) = delete; // new
Surface& operator=(const Surface&) = delete; // new
};
By deleting the implementation of the copy constructor and copy assignment operator you prevent your Surface objects from being copied (which would likely crash your program anyway). Any attempt to copy Surface objects will now result in a compile time error.
Only a suggestion, my first choice would always be to use std::vector.

Related

Smart pointer which can change ownership at runtime (C++)

I often encounter a situation when I have complex class (e.g. implementing some numerical algorithm like Partial Differential Equation Solver) with data arrays which it can either own or bind from external context depending on use case. The problem is how to make robust destructor for such class. Simple way is to make boolean flag which indicates wheather the array is owned. E.g.
// simplest example I can think about
class Solver{
int nParticles;
bool own_position;
bool own_velocity;
double* position;
double* velocity;
// there is more buffers like this, not just position and velocity, but e.g. mass, force, pressure etc. each of which can be either owned or binded externally independently of each other, therefore if there is 6 buffers, there is 2^6 variants of owership (e.g. of construction/destruction)
void move(double dt){ for(int i=0; i<n; i++){ position[i]+=velocity[i]*dt; } }
~Solver(){
if(own_position) delete [] position;
if(own_velocity) delete [] velocity;
}
};
Naturally, this motivates to make a template wrapper around the array pointer (should I call it smart pointer ?):
template<typename T>
struct Data{
bool own;
T* data;
~Data{ if(own)delete [] T; }
};
class Solver{
int nParticles;
Data<double> position;
Data<double> velocity;
void move(double dt){ for(int i=0; i<n; i++){ position.data[i]+=velocity.data[i]*dt; } }
// default destructor is just fine (?)
};
Question:
This must be common pattern, do I reinvent a wheel here?
Is something like this in C++ standard library ? (sorry, I'm rather a physicist than a programmer)
are there some catches to think about ?
----------------------------------------
EDIT: To make clear what bind to external contex mean (as Albjenow suggested):
case 1) private/internal work array (no shared ownership)
// constructor to allocate own data
Data::Data(int n){
data = new double[n];
own = true;
}
Solver::Solver(int n_){
n=n_;
position(n); // type Data<double>
velocity(n);
}
void flowFieldFunction(int n, double* position, double* velocity ){
for(int i=0;i<n;i++){
velocity[i] = sin( position[i] );
}
}
int main(){
Solver solver(100000); // Solver allocates all arrays internally
// --- run simulation
// int niters=10;
for(int i=0;i<niters;i++){
flowFieldFunction(solver.n,solver.data.position,solver.data.velocity);
solver.move(dt);
}
}
case 2) Bind To External data array (e.g. from other class)
Data::bind(double* data_){
data=data_;
own=false;
}
// example of "other class" which owns data; we have no control of it
class FlowField{
int n;
double* position;
void getVelocity(double* velocity){
for(int i=0;i<n;i++){
velocity[i] = sin( position[i] );
}
}
FlowField(int n_){n=n_;position=new double[n];}
~FlowField(){delete [] position;}
}
int main(){
FlowField field(100000);
Solver solver; // default constructor, no allocation
// allocate some
solver.n=field.n;
solver.velocity(solver.n);
// bind others
solver.position.bind( field.position );
// --- run simulation
// int niters=10;
for(int i=0;i<niters;i++){
field.getVelocity(solver.velocity);
solver.move(dt);
}
}
Here is a simple way to do what you want without having to write any smart pointer yourself (it would be hard to get the fine details correct) or writing a custom destructor (which would mean more code and bug potential from the other special member functions required by the rule of five):
#include <memory>
template<typename T>
class DataHolder
{
public:
DataHolder(T* externallyOwned)
: _ownedData(nullptr)
, _data(externallyOwned)
{
}
DataHolder(std::size_t allocSize)
: _ownedData(new T[allocSize])
, _data(_ownedData.get())
{
}
T* get() // could add a const overload
{
return _data;
}
private:
// Order of these two is important for the second constructor!
std::unique_ptr<T[]> _ownedData;
T* _data;
};
https://godbolt.org/z/T4cgyy
The unique_ptr member holds the self-allocated data, or is empty when externally owned data is used. The raw pointer points to the unique_ptr contents in the former case, or the external content in the latter case. You could modify the constructors (or only make them accessible via static member functions like DataHolder::fromExternal() and DataHolder::allocateSelf() which return DataHolder instances created with the appropriate constructor) to make accidental misuse harder.
(Note that the members are initialized in the order they are declared in the class, not in the order of the member initializer lists, so having the unique_ptr before the raw pointer is important!)
And of course, this class cannot be copied (due to the unique_ptr member) but can be move-constructed or -assigned (with the correct semantics). Works out of the box as it should.
One solution is to separate data ownership from your solver algorithm. Having the algorithm optionally manage lifetime of its inputs isn't good design because it leads to entanglement of separate concerns. The solver algorithm should always refer to already existing data. And have another extra class that owns data, if necessary, and have lifetime no shorter than that of the algorithm, e.g.:
struct Solver {
int nParticles;
double* position;
double* velocity;
};
struct Data {
std::vector<double> position, velocity; // Alternatively, std::unique_ptr<double[]>.
template<class T>
static T* get(int size, std::vector<T>& own_data, T* external_data) {
if(external_data)
return external_data;
own_data.resize(size);
return own_data.data();
}
double* get_position(int nParticles, double* external_position) { return get(nParticles, position, external_position); }
double* get_velocity(int nParticles, double* external_velocity) { return get(nParticles, velocity, external_velocity); }
};
struct SolverAndData {
Data data;
Solver solver;
SolverAndData(int nParticles, double* external_position, double* external_velocity)
: solver{
nParticles,
data.get_position(nParticles, external_position),
data.get_velocity(nParticles, external_velocity)
}
{}
SolverAndData(SolverAndData const&) = delete;
SolverAndData& operator=(SolverAndData const&) = delete;
};
int main() {
SolverAndData a(1, nullptr, nullptr);
double position = 0;
SolverAndData b(1, &position, nullptr);
double velocity = 0;
SolverAndData c(1, nullptr, &velocity);
SolverAndData d(1, &position, &velocity);
}

Segmentation fault when using vectors in the class and constructor

I was doing a list of programming projects, and this project is to make a 15 puzzle (slide puzzle). I was working on the project when I hit a small roadblock.
My code compiles just fine, but when I run it, I get a segmentation fault at line 12: pos[0] = x;
#include <iostream>
#include <vector>
#include <stdlib.h>
#include <time.h>
using namespace std;
class Tile{
private:
vector<int> pos;
int value;
public:
Tile(int x, int y, int value_){
pos[0] = x;
pos[1] = y;
value = value_;
}
~Tile(){}
int getPos(int a){return pos[a];}
void setPos(int a, int b){pos[a] = b;}
};
int main(){
Tile tile1(1, 2, 10);
Tile* t1;
t1 = &tile1;
// returns position "x"
cout << t1->getPos(0);
return 0;
}
I mean, I could just do the whole project without having to use vectors/arrays to handle the position, but I do still want to know, for my own understanding in the future, why this doesn't work.
Based on the debug that I ran, the program is having trouble initializing the value of the pos[] vector.
Another issue: probably related, I tried setting the size of the vector when it was instantiated.
vector<int> pos(2);
But then I get the debug error:
error: expected identifier before numeric constant
Not sure whats going on here. I've tried a bunch of different things but I can't seem to figure out why my vectors don't work inside of classes.
I'm sure there are a hundred ways I could have done this little piece better, and I would love to know how you would have fixed it, but I also need to know what is wrong, specifically in the context of what I have written and tried.
Thanks.
I tried setting the size of the vector when it was instantiated.
vector<int> pos(2);
But then I get the debug error:
error: expected identifier before numeric constant
That's a compilation error, not a debug error.
You can't initialise members like that. However, you can (and should) initialise them using the parent constructor:
Tile(int x, int y, int value_)
: pos(2)
{
pos[0] = x;
pos[1] = y;
value = value_;
}
Currently you're just leaving your vector empty then accessing (and writing to!) elements that don't exist.
You really don't want a vector for this, anyway: that's a lot of dynamic allocation. How about a nice array? Or just two ints.
As mentioned in other answers, your vector is empty and your code is attempting to assign non-existent elements.
The solution is to always use initialisers instead of assignment. Rewrite your constructor as follows:
Tile(int x, int y, int value) :
pos{x, y},
value{value} {}
Note that the constructor body is now empty. All initialisation happens where it should — in the initialiser list.
Apart from that, your class does not need an explicitly defined destructor; the default destructor works just fine.
There are other issues with this class — for instance, what happens when the user does tile.setPos(3, 4)? A rule of thumb of good API design is to make it impossible to misuse the API.
Here’s how I would write your Tile class instead:
struct Tile {
int x;
int y;
int value;
Tile(int x, int y, int value) : x{x}, y{y}, value{value} {}
};
The getter and setter in your case wasn’t really doing any meaningful work. There’s an argument to be made to hide all data members behind accessors to future-proof access control. I’m no longer convinced this is actually useful but just in case, here’s a solution with that, too:
class Tile {
int x_;
int y_;
int value_;
public:
Tile(int x, int y, int value) : x_{x}, y_{y}, value_{value} {}
int x() const { return x; }
int& x() { return x; }
int y() const { return y; }
int& y() { return y; }
int value() const { return value; }
};
This makes x and y readable and writable (via assignment: t.x() = 42;), and value only readable. Other APIs are possible, with different sets of trade-offs. The important thing is to be consistent.
Your constructor doesn't set the size, so when you try to access/modify its contents, you are probably getting the exception.
Tile(int x, int y, int value_) : pos(2) {
pos[0] = x;
pos[1] = y;
value = value_;
}
You can use the initialization list of the constructor to call the vector's constructor, as in the code above.
There are couple of issue in the given code, which I have resolved and added comment in the code.
Issue in setPos and getPos might raise segmentation fault must be handle.
Added checks for the same.
#include <iostream>
#include <vector>
#include <stdlib.h>
#include <time.h>
using namespace std;
class Tile{
private:
vector<int> pos;
int value;
public:
Tile(int x, int y, int value_){
pos.push_back(x); // this is equivalent to pos[0] = x, in this case
pos.push_back(y); // this is equivalent to pos[0] = y, in this case
value = value_;
}
~Tile(){}
int getPos(int a){
if(a >= pos.size()){
return -1; // if a is greater than size then pos[a] will raise the segmentation fault
}
return pos[a];
}
void setPos(int a, int b){
if(a >= pos.size()){
pos.resize(a+1); // to avoid segmentation fault, we are increasing the size if the given index is higher
// resize initialise the value with 0 as default value.
}
pos[a] = b;
}
};
int main(){
Tile tile1(1, 2, 10);
Tile* t1;
t1 = &tile1;
// returns position "x"
cout << t1->getPos(0);
return 0;
}

C++ Using member functions from a similar virtual public class

Suppose I have a bunch of inherited classes like this:
...and they all serve the purpose of making all sorts of polynomials. Class X is mainly a variable tank, classes A, B, etc are all virtual public X and each creates ont type of polynomial, class Y makes the calls. Besides A and B, any other class can be added.
Now, everything works but for a newly added "virtual public" class I need to reuse some member function(s) from other classes, here from A inside class B. I tried to make the simplest example:
#include <iostream>
#include <cmath>
#include <functional>
// variable tank
class X
{
protected:
// general variables
double *m_c;
int m_n;
double m_w;
// funcX related
double m_r;
int m_i {0};
public:
~X() = default;
/* Simple bracketed root-finding. This is called from more than
* one "virtual public" classes.
*/
const double funcX(const double &x, const double &y, \
std::function<const double(const double&, const int&)> fp, \
const int &k)
{
double a {x}, b {y}, fmid;
while (m_i<100)
{
m_r = 0.5*(a + b);
fmid = fp(m_r, k);
if (fabs(b-a) <= 1e-3)
break;
if (fmid < 0)
b = m_r;
else
a = m_r;
++m_i;
}
return m_r;
}
};
// one of the many classes that generate polynomials
class A: virtual public X
{
public:
void funcA(const int &n)
{
// set order
m_n = n;
// calculate X::m_c[i]
m_c = new double[m_n+1];
for (short i=0; i<=m_n>>1; ++i)
{
int sgn {i%2 ? -1 : 1};
m_c[i<<1] = sgn/((i + 1.0)*(i + 1.0));
}
// The polynomial is zero somewhere, use funcX() to find where.
m_w = funcX(5.0, 0.0, \
[this](const double &x, const int &n) \
{ return calcA(x, n); }, \
m_n);
}
// calculates the value of the polynomial of order n, at x
const double calcA(const double &x, const int &n) const
{
double out {static_cast<double>(m_c[0])};
for (short i=1; i<=n; ++i)
out = m_c[i] + x*out;
return out;
}
};
class B: virtual public X
{
private:
A m_a; // otherwise the lambda function does not "catch" it
public:
void funcB(const int &n)
{
// same as in A
m_n = n;
// same as in A, calculate coefficients
m_c = new double[m_n+1];
for (short i=0; i<=m_n; ++i)
{
int sgn {i%2 ? -1 : 1};
m_c[i] = sgn/((i + 1)<<1);
}
/* Here I need A::calcA(). Instead of duplicating the code,
* I want to call it through X::funcX(). The code compiles,
* but it crashes.
*/
m_w = funcX(0.5, 1.0, \
[this](const double &x, const int &n) \
{ return m_a.calcA(x, n); }, \
m_n);
}
const double getW() const { return m_w; }
};
class Y: public A, public B
{
public:
Y(const int &n, const int &i)
{
// call one of the "virtual public" classes through i
switch (i)
{
case 1: funcA(n); break;
case 2: funcB(n); break;
}
}
void printC() { for (short i=0; i<=m_n; ++i) std::cout << m_c[i] << '\n'; }
void printW() { std::cout << m_w << '\n'; }
void printA(const double &x, const double &n) { std::cout << A::calcA(x, n) << '\n'; }
};
int main(int argc, char *argv[])
{
int N {6};
Y *y;
for (short i=1; i<=2; ++i)
{
y = new Y(N, i);
y->printC();
y->printW();
y->printA(1.2, N);
}
return 0;
}
class X:
X::funcX() is a simple root-finding algorithm which gets called in more than one virtual public classes (A, B, etc). m_c, m_n, m_w are shared variables.
classes A and B:
their main function is funcA() (and funcB(), and so on) and it creates the polynomial (in the body, there's a for loop), based on the calculated order, X::m_n. Evaluating the polynomial is A::calcA(). This needs to be either called by class B, too, or redefined. I'd rather avoid the latter because of the code bloating. It also doesn't look very "professional" for my fairly beginner level...
class Y
This calls any of the virtual public classes based on argument i (the switch/case).
The code compiles, but crashes. It prints the case for. This example points to A::funcA() as the culprit, but in the original program I can see that the coeficients, m_c[i], are not even initialized with dynamic memory, as in trying to print out m_c[0] crashes. I tried moving the new double[] insode the function in A, but that doesn't work.
I don't know how to make it. Does this make sense, is it possible? If yes, how?
Edit: Forgot to add that I can't just move calcA() from A to the top, in X, because each polynomial is evaluated differently, as in there are shortcuts, changes, in every one that makes it possible to have different, optimized evaluations for each polynomial. I could make X::calcA() a universal one, but there will be a performance penalty, which I'd rather not pay.
It seems that your problem is induced by problems with design. When you need to use methods from other class that may mean:
The is a problem with "single responsibility" principle. Class does too much. For example numerical equation solving algorithms are self-sufficient entities and shouldn't be part of polynomial. They can work with any polynomial.
There is a problem with inheritance tree. For example a common ancestor should be created and that common methods should be in it. Note, that if you can't find short and understandable name for that ancestor, then this is not the solution.
Inheritance is not used properly. For example I can't see virtual methods in your code which is strange.
Let's get closer to your example. You are using virtual multiple inheritance which is considered to be very heavy pattern and usually should not be used. Moreover, there are no virtual methods in your code, so you actually do not use inheritance at all. You either must drop inheritance, or think of common methods which make sense for all your classes. For functions this seems to be an ability to calculate function value in specified point. Then move all code, that is not describing polynomials or functions out of the classes. Move out numerical solvers. This will allow to reuse them for all your classes, that support needed interface. Get rid of Y class at all. It seems, that it is needed to emulate virtual methods with switches and enums. You don't need it, rename funcA and funcB just to func if they are semantically the same and do the same thing for different types of polynomials.

Making an Array that stores pairs and or a class in c++?

I've looked for a while and none of the answers seem to fully fit my question, that or I've just hit a mental barrier.
I've made a class that has set and get methods and an output method called pairs, this works with two ints x+y and they each have set and get methods individually. I need to make a dynamic array based on the code below that can store these pairs. I'm not looking to be spoon fed I just want to know if my logic is correct and be pointed in the right direction.
class dynArray //a dynamic(ish) array class
{
public:
dynArray() : data(0), sz(0) { }
dynArray(int size) : sz(size) { data = new int[sz]; }
virtual ~dynArray() { if(data) delete [] data; } //destructor method
int& operator [] (int idx) { return data[idx]; } //operator overload!
int size() { return sz; }
private:
int * data;
int sz;
};
Pairs class
class pairs{
public:
pairs() : x(0), y(0) { }
void setX(int);
void setY(int);
void outputXY(int, int);
int getX();
int getY();
private:
int *x;
int *y;
};
void pairs::setX(int a)
{
x = &a;
}
void pairs::setY(int b)
{
y = &b;
}
int pairs::getX()
{
return *x;
}
int pairs::getY()
{
return *y;
}
void pairs::outputXY(int c, int d)
{
x = &c;
y = &d;
cout << "Number 1:" << c << " Number 2:" << d;
}
I'm very rusty with c++ so my logic has just vanished, I'm struggling to see how I would make an array that can store two ints within one element. Then i thought maybe I could make the pair class an array that stores two numbers in element 0 and 1 and then make an array of that class using the dynamic code, figuring out how to do this has stumped me though. All I really need is a helpful link or terms to be thrown at me as I really want to learn the code myself. Any help would be really appreciated, Thanks.
I would recommend using the STL library, in particular std::pair and some kind of container like std::lists or std::vectors. In order to implement some own, additional functionality, you may create your own class derived from those.
(Not enough "reputation" to post this answer as comment...)
If I correctly understood your issue, I'd suggest using a std::vector to store your elements since it will also spare you the memory management hassle
class dynArray //a dynamic(ish) array class
{
public:
dynArray() {}
dynArray(int size) { data.resize(size); /* Initialize with default-constructed elements */ }
pairs& operator [] (int idx) { return data[idx]; }
size_t size(){ return data.size(); }
private:
std::vector<pairs> data;
};
Just provide some insertion methods and you'll be good to go. Notice that the design will greatly simplify itself with the above solution.
Another solution as user236012 pointed out could be to use std::pair (specifically std::pair<int,int>) and just store the pairs in the vector.
If you intend to use the pairs class, be aware that your code is wrong:
void pairs::setX(int a)
{
x = &a; // Address of the actual parameter - address on the stack
}
therefore I'd suggest to either store plain values or use std::pair as suggested. There's really little point in storing pointers to integer values (they'd even be more expensive on many architectures).
A c-like way:
int * getPair(int idx)
{
return &data[idx*2];
}
void setPair(int idx, int * xy)
{
data[idx*2]=xy[0]; data[idx*2+1]=xy[1];
}

Constructor in implementation versus header

The constructor should, to my knowledge, be defined in the implementation file but I've only been able to find examples with the class inside one main file instead of split into a .h and .cpp file
All I need to know is if my following code is separated in an acceptable manner..
Entity.h:
using namespace std;
class cEntity {
private:
/*-----------------------------
----------Init Methods---------
-----------------------------*/
int *X, *Y;
int *Height, *Width;
public:
/*-----------------------------
----------Constructor----------
-----------------------------*/
cEntity (int,int, int, int);
/*-----------------------------
----------Destructor-----------
-----------------------------*/
~cEntity ();
/*-----------------------------
----------Set Methods----------
-----------------------------*/
/*Set X,Y Methods*/
void setX(int x){*X=x;};
void setY(int y){*Y=y;};
void setXY(int x, int y){*X=x; *Y=y;};
/*Set Height, Width Methods*/
void setHeight(int x){*Height=x;};
void setWidth(int x){*Width=x;};
void setDimensions(int x, int y){*Height=x; *Width=y;};
/*-----------------------------
----------Get Methods----------
-----------------------------*/
/*Get X,Y Methods*/
int getX(){return *X;};
int getY(){return *Y;};
/*Get Height, Width Methods*/
int getHeight(){return *Height;};
int getWidth(){return *Width;};
};
and Entity.cpp:
#include "Entity.h"
cEntity::cEntity (int x, int y, int height, int width) {
X,Y,Height,Width = new int;
*X = x;
*Y = y;
*Height = height;
*Width = width;
}
cEntity::~cEntity () {
delete X, Y, Height, Width;
}
I would also like to say thanks to everyone for being so helpful, especially on my first question!
cEntity::cEntity (int x, int y, int height, int width) {
is correct
X,Y,Height,Width = new int;
not so much. That sets Width to a new int, but not the rest. You probably intended:
X = new int(x);
Y = new int(y);
Height = new int(height);
Width = new int(width);
Note that this method of construction will not work for objects without assignment/copy, like references. For some objects, it's also slower than constructing them in place. As such, the preferred way to construct is like so:
cEntity::cEntity (int x, int y, int height, int width) {
:X(new int(x))
,Y(new int(y))
,Height(new int(height))
,Width(new int(width))
{}
This is better, but if any exceptions are thrown, you'll have to somehow deallocate the ones that were allocated. Better is to make each of those members a std::unique_ptr<int>, so they'll deallocate themselves and save you many headaches.
Yes, it's OK.
However, there is a problem with your constructor and destructor.
What your code actually does is allocating one int and your destructor deallocates one int also.
Anyway, there is no need to use pointers here.
Somewhat better implementation (if we don't use smart pointers), could be:
[Entity.h]
private:
/*Private fields*/
int X, Y;
int Height, Width;
[Entity.cpp]
cEntity::cEntity (int x, int y, int height, int width) {
X = x;
Y = y;
Height = height;
Width = width;
}
cEntity::~cEntity () {
}
And one more thing. Try to avoid using namespace std; in your header files. If you do, you force those who include your header to use this using statement and it can provoke namespace clashes.
Your separation is fine. The implementations of those functions is wrong, but you've separated them from the declaration suitably. (They don't allocate or free as many objects as you think they do.)
Yes. For the separation at least, that's generally the best way to do it.
As for the actual implementation you have some issues. I am not really sure what you are trying to do with the constructor or if you have the correct data types for the class member variables but something seems off.
Any method defined in the class directly is implicitly inlined, including the constructor.
I.e.
class MyClass
{
public:
MyClass() {};
};
defines an inline constructor, which may (or may not) improve your code performance,
Whereas
class MyClass
{
public:
MyClass();
};
MyClass::MyClass()
{
};
is not inlined, and therefore won't have those benefits. Both options are correct C++ though.
Just my 2 cents.
P.S And yes, when you decide to store pointers inside a class in this manner, you open a Pandora box.