Совместное использование данных с объектами, созданными с помощью оператора [] (const size_t & i) - например, сложный векторный контейнер - PullRequest
1 голос
/ 26 января 2011

когда я хочу поделиться данными, я часто попадаю в беспорядок, используя оператор [] (const size_t & i) в c ++. Я хотел спросить, есть ли шаблон проектирования, который я должен использовать - или лучший способ вообще.

Написание сложного векторного контейнера иллюстрирует мою проблему - хотя у меня были похожие проблемы при написании других контейнеров.

Это код, который я хочу написать:

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);             
}

Он точно соответствует моему class vec (который является просто массивом парных чисел).

Моя проблема заключается в том, как правильно управлять ссылками на комплексные числа, когда данные передаются таким образом.

То, как я сейчас это делаю, кажется ужасным. Я определяю свой сложный класс следующим образом:

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;}

}

А затем в классе cvec добавление набора ссылок в контейнер std :: vector, например, так:

 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];}   
 }

Это работает, но кажется довольно шатким. Я хотел спросить, есть ли лучший способ управления ссылками, когда вы хотите обмениваться данными между классами. Существует ли шаблон проектирования, который мне следует использовать при совместном использовании данных.

Большое спасибо, Том

...