当一个类包含另一个类

时间:2016-07-05 13:25:18

标签: c++

我举了下面的例子来说明我的问题。假设Abc是一个将使用另一个类(Def)的类。假设Def是一个包含许多类成员的大类(复制代价很高),让指向Def对象的指针成为Abc类的一部分更有意义。然后在实现Abc类函数do1时,它可以通过其指针pDef引用Def对象。

class Abc
{
  public:
        Abc(Def &def)
        {
           pDef = &def;
        }
        ~Abc()
        {
         }
        void do1();
   private:
        Def *pDef;

}

但是,如果我以这种方式实现类Abc,我将面临Def指针可能无效的风险。关于改进这个班级设计的任何想法?我的一个想法是使用共享指针:

 class Abc
    {
      public:
            Abc(boost::shared_ptr<Def> def)
            {
               pDef = def;
            }
            ~Abc()
            {
             }
            void do1();
       private:
            boost::shared_ptr<Def> pDef;

    }

编辑:我想说明我的主要目的是在构建类Abc时避免昂贵的复制操作。对我来说,使用共享指针和James Adkison的解决方案(接受的答案)都可以解决问题。但是对昂贵的Def对象的影响可能会有所不同。使用共享指针将保留对象的许多副本,而使用James Adkison的解决方案只保留Def对象的一个​​副本。

3 个答案:

答案 0 :(得分:3)

  

假设Def是一个包含许多类成员的大型类

我认为这意味着复制def split_key(k): if '#' in k: return k.split('#')[0] else: return k def group_keys(keys): for K, G in groupby(keys, key=split_key): yield split_key(K), sum(1 for g in G) def slice_row(mapping, row): i = 0 for key, length in group_keys(mapping): if length == 1: yield key, row[i] else: yield key, row[i:i + length] i += length print(dict(slice_row(mapping, row[0]))) # >>> {'key4': 'val4', 'key6': ['val9', 'val10'], 'key5': ['val5', 'val6', 'val7', 'val8'], 'key3': 'val3', 'key1': 'val1', 'key2': 'val2'} 类的成本很高。但是,使用C ++ 11,您可以为Def实现移动语义,并使Def实现简单有效。

注意:此答案基于以下假设:问题使用任何指针(智能或其他)的唯一原因是避免昂贵的副本。

示例代码

Abc

现在class Def { public: Def() {} Def(const Def& other) { /* ... */ } // Copy constructor even though it's expensive Def(Def&& other) { /* ... */ } // Move constructor for efficiency Def& operator=(const Def& other) { /* ... */ } // Copy assignment Def& operator=(Def&& other) { /* ... */ } // Move assignment }; 类支持复制语义,即使复制类可能很昂贵。但是,它还支持移动语义,以便在不需要副本时有效使用。

Def

如果用例实际上支持共享所有权语义,我只提倡使用class Abc { public: Abc() {} Abc(const Def& def) : mDef(def) {} // Perform an expensive copy Abc(Def&& def) : mDef(std::move(def)) {} // Perform a move // Implement any other member functions which could accept Def // via copy or move private: Def mDef; };

答案 1 :(得分:1)

如果可以使用引用,为什么要使用指针?

class Abc
{
public:
    Abc(Def &def) : pDef(def)
    {
    }

    void do1();
private:
    Def& pDef;
}

你没有通过所有权,因此不需要指针。

将引用想象为一个永远不能为null的指针。

答案 2 :(得分:0)

这是std::shared_ptr的用途。如果使用std::shared_ptr,指针将始终有效(只要遵循所有非常简单的规则)。