【问题标题】:Creating an array of objects containing references创建包含引用的对象数组
【发布时间】:2012-02-29 08:36:11
【问题描述】:

以下情况最好的处理方法是什么?

假设我有一些行为应该像这样

class Foo
    {
    public:
         Foo(Bar& bar):m_bar(bar){}
    private:
         Bar& m_bar;
    };

Foo:s 必须具有对 Bar:s 的有效引用。不同的 Foo:s 也需要不同或相同的 Bar:s。

我想将 Foo:s 存储在一个数组中。但是,由于 Foo 需要一个非默认的构造函数,所以它不起作用。

我可以创建一个指向 Foo:s 的指针数组,但是我需要为该数组中的每个对象调用 new 和 delete。

我可以这样定义 Foo

class Foo
    {
    public:
         void init(Bar& bar)
             {
             m_bar=&bar;
             }
    private:
         Bar* m_bar;
    };

,但是可以创建未初始化的 Foo:s。

一些新的展示位置怎么样?

【问题讨论】:

    标签: c++ arrays object pointers reference


    【解决方案1】:

    首先,对不起,我的第一个答案是我弄错了问题。 我希望这是一个更好的解决方案:您可以创建一个 vector 的元素,而无需像这样的默认构造函数:

    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    
    class Foo 
    { 
    public: 
        Foo(int& bar): m_pBar(bar)
        { } 
    
        Foo& operator=(const Foo& other)
        { m_pBar = other.m_pBar;  }
    
        int Get()
        { return m_pBar; }
    
    private: 
        int& m_pBar; 
    }; 
    
    
    int main(int argc, char** argv)
    {
        int test[10]  = { 0 };
    
        vector<Foo> vect;
        for (int& i: test)
            vect.emplace_back(i);
    
        test[0] = 1;
        cout << vect[0].Get() << endl;
    
        return 0;
    }
    

    【讨论】:

    • 但是如果 Foo 还包含一个我不想复制的 BLOb?
    • 我不确定您在哪里看到复制。 也要小心预期的优化。首先,“复制”可能会由编译器在“移动”中进行优化,其次可能不会那么慢,第三您也可以使用 Blob 的引用...
    • 好吧,赋值运算符将数据从“other”复制到“*this”。当我说 BLOb 时,我的意思可能是一些兆。
    • 那么使用智能指针或引用来复制 blob 是非常合理的。
    【解决方案2】:

    您仍然可以使用指针,但不要使用原始指针,而是使用 unique_ptrs。这些在 c++11 中可用,但如果您使用的是较旧的编译器,则可以使用 boost 实现。

    例如

    class Foo
    {
    public:
      Foo(unique_ptr<Bar> bar):m_pBar(bar){}
    private:
      unique_ptr<Bar> m_pBar;
    };
    

    这样您就不必担心在 Bar 对象上调用 delete,因为一旦不再引用它们,它们就会被删除。

    那么你就可以像这样使用Foo了

    unique_ptr<Bar> pBar(new Bar());
    Foo(pBar);
    

    编辑:更改为使用 unique_ptr 而不是 shared_ptr 并添加示例用法

    【讨论】:

    • 我认为unique_ptr 会更好。无需在多个线程之间共享数据。
    • 同意。我会更改我的答案以反映这一点。
    • 它仍然会导致 new 为每个对象调用,不是吗?
    • 是的,您仍然需要调用 new,更改我的答案以显示示例
    • 但我想要一个 Foo:s 数组和 Foo 类不变。你的意思是 unique_ptr foos=new unique_ptr[n]
    【解决方案3】:

    最后我用下面的构造函数实现了一个自定义容器:

    template<class T>
    template<class U,class V>
    Array<T>::Array(unsigned int n,U source_iterator,const V& source_resource):memory(n*sizeof(T))
        {
        data=(T*)memory.pointerGet();
        unsigned int k;
        try
            {
            for(k=0;k<n;k++)
                {
                new(data+k)T(*source_iterator,source_resource);
                ++source_iterator;
                }
            }
        catch(...)
            {
            while(k>0)
                 {
                 k--;
                 data[k].~T();
                 }
            throw;
            }
        length=n;
        capacity=n;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-04-16
      • 1970-01-01
      • 1970-01-01
      • 2010-12-31
      • 2021-09-22
      • 1970-01-01
      • 2019-02-20
      • 1970-01-01
      • 2014-07-20
      相关资源
      最近更新 更多