效率与封装:首选哪种?

时间:2015-10-12 14:03:07

标签: c++ oop

在类中实现良好的封装将确保没有外部力量可以修改对象的内部。在C ++中,这意味着一个类应该分配所有需要动态分配的对象本身。如果要对这样的对象进行复制,则意味着必须复制许多内部属性(不仅仅是指针)。这可能会导致某些程序的大量开销。下面给出一个例子:

class A { };

class B : public A {
private:
  std::vector< const A* > m_children;
public:
  B( ) : m_children( 0 ) { }

  B( const B& src ) : m_children( src.m_children.size( ) ) { // Make it a copy of src
    for ( unsigned int i = 0; i < m_children.size( ); i++ )
      // Make a full copy of src element (and all children, not implemented here)
      m_children[ i ] = copyOf( *src.m_children[ i ] ); // Dynamically allocates copy!
  }

  ~B( ){ // Deallocate all children
    while ( !m_children.empty( ) ){
      delete m_children.back( ); // Get last element in array
      m_children.pop_back( ); // Remove last element
    }
  }

  void addChild( const B& child ) {
    m_children.push_back( new B( child ) ); // Notice dynamic allocation
  }
};

B build( int x ) {
  B b;
  if ( x != 0 ) b.addChild( build( x - 1 ) );
  return b;
}

int main( int argc, char **argv ) {
  B b = build( 10 ); // Make 10 generations with 1 child each
}

每次将一个孩子添加到B时,它都会再次完全分配(包括所有孩子)。这确实提供了良好的封装,因为无论在什么情况下,父进程都是唯一可以实际修改其子进程(或解除分配指针)的进程。此外,它完全有责任自行销毁这些儿童。这在内存管理方面不是很有效。必须为每个build()函数动态创建和删除许多其他对象。

如何有两种可能性:
要么我在这里遗漏了一些东西,这可以通过实现良好的封装和效率来实现。如果是这种情况,请告诉我 或者,这是唯一的方法,然后:通常首选哪种方式;强大的封装(没有外部访问),或者在类外部分配对象,因此内存操作发生的次数较少,但是外部世界&#34;有权访问这些指针及其对象(安全性较低)?

1 个答案:

答案 0 :(得分:0)

您应该使用移动语义来避免不必要的复制。您需要向class B添加移动构造函数。

class B
{
    B(B&& rhs)
   {
       std::swap(m_children, rhs.m_children);
   }
}

然后,您可以将addChild()功能更改为:

class B
{
    void addChild(B child) 
    {
        m_children.push_back( new B( std::move(child) ) );
    }
}

为什么会这样?在build()函数中,您将临时函数传递给addChild()。这将调用移动构造函数,然后您只需向前移动对象。

LIVE DEMO - 删除了复制构造函数,因此您可以看到不涉及复制。

相关问题