when I want to share data I often get in a mess using the operator[] (const size_t& i) in c++. I wanted to ask if there is a design pattern that I should be using - or a better way altogether.
Writing a complex vector container illustrates my problem - although I've had similar problems writing other containers.
This is the code that I want to write:
class complex; //forward declaration to my complex number container.
//my complex vector container
class cvec{
private:
size_t m_size; //The number of complex numbers in the vector
/* I want my data stored
* real(0), imag(0), real(1), imag(1) ... real(m_size-1), imag(m_size-1)
* so that I can easily pass the data to blas routines - for example.
*/
double* m_data; // 2 * m_size
public:
//return a reference to constant complex number
const complex& operator[](const size_t& i) const;
//return a reference to a complex number that points to m_data.
//The user should be able to alter m_data by altering the returned complex number
complex& operator[](const size_t& i);
}
It mirrors exactly my class vec
(which is just an array of doubles).
My problem is how to manage the references to the complex numbers in a sane way when the data is shared in this manner.
The way I am doing it at the moment feels ugly. I define my complex class like this:
class complex{
private:
double* m_data; //a pointer that always contains 2 elements
bool m_own; //whether this class owns the data - or whether the data belongs to cvec
void alloc_data(); //allocate the memory if m_own == true
public:
//A constructor when the complex number owns its data.
complex(const double& x, const double& y) : m_own(true)
{ alloc_data(); m_data[0] = x; m_data[1]=y;}
//A constructor when it does not
complex(double* data) : m_own(false)
{ m_data = data;}
}
And then in the cvec class adding a set of references in a std::vector container like so
class cvec{
private:
...
std::vector<boost::shared_ptr<complex> > m_complex_data; 开发者_运维技巧
void alloc_data() { //I use calloc as I believe this is byte aligned while the new operator is not...
if (m_size>0)
m_data = ( double* ) calloc(2*m_size, sizeof(double));
m_complex_data.resize(m_size);
for(size_t i=0;i<m_size;++i){
//Pass a pointer to data to the new complex class
boost::shared_ptr<complex> cptr( new complex(m_data + 2*i) );
m_complex_data[i] = cptr ;
}
}
public:
//Return the reference
const complex&
operator[](const size_t& i) const
{return *m_complex_data[i];}
}
This works but feels rather precarious. I wanted to ask if there is a better way of managing references when you want to share data between classes. Is there a design pattern that I should be using when sharing data in this way.
Many thanks, Tom
精彩评论