开发者

Sharing data with objects created with operator[](const size_t& i) - e.g. a complex vector container

开发者 https://www.devze.com 2023-02-06 17:40 出处:网络
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.

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

0

精彩评论

暂无评论...
验证码 换一张
取 消