与使用operator[](const size_t& i)创建的对象共享数据 - 例如复杂的向量容器

发布于 2024-10-14 13:54:02 字数 2543 浏览 6 评论 0原文

当我想要共享数据时,我经常在 C++ 中使用运算符[] (const size_t& i) 陷入混乱。我想问是否有我应该使用的设计模式 - 或者更好的方法。

编写一个复杂的向量容器说明了我的问题 - 尽管我在编写其他容器时也遇到了类似的问题。

这是我想要编写的代码:

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

这可行,但感觉相当不稳定。我想问当您想在类之间共享数据时是否有更好的方法来管理引用。以这种方式共享数据时,我应该使用一种设计模式吗?

非常感谢,汤姆

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文