繁体   English   中英

C ++ STL容器和就地构造

[英]C++ STL container and in-place construction

请考虑以下事项:

class CMyClass
{
public:
  CMyClass()
  {
    printf( "Constructor\n" );
  }
  CMyClass( const CMyClass& )
  {
    printf( "Copy constructor\n" );
  }
};

int main()
{
  std::list<CMyClass> listMyClass;

  listMyClass.resize( 1 );

  return 0;
}

它产生以下输出:

构造函数

复制构造函数

现在我的问题是:我如何避免复制构造函数? 或者换一种方式:如何在没有不必要的复制操作的情况下在STL容器内创建对象。 有没有办法使用默认构造函数进行“就地”构造?


更新 - 答案到目前为止:

  1. 它无法完成
  2. 请改用指针或智能指针。

智能指针对我的应用来说太过分了。 但我真的很想知道为什么不能这样做。 这似乎是一件显而易见的事情。 还有其他想法吗? 如果它有效,我甚至会接受一个讨厌的黑客......


我想我刚从这里提出的所有评论和答案中找到了我的问题的解决方案。 解决方案是构造一个空对象并将其保留,以便以后使用它来制作干净的副本。 然后,您可以使用其中一个引用方法(如push_back或insert)。 这仍然为每个插入的新对象调用复制构造函数,但至少它不是默认构造函数和复制构造函数:

int main()
{
  CMyClass Empty;

  std::list<CMyClass> listMyClass;

  for ( int c=0; c<10; ++c )
  {
    listMyClass.push_back( Empty );
  }

  return 0;
}

按照设计,所有C ++标准库容器都存储副本。 因此,如果您希望将值存储在容器中,则无法避免对复制构造函数的调用 - 唯一的出路是存储指针。 如果要减轻复制的开销,请调查引用计数的使用。

使用指针

std::list<CMyClass*> listMyClass;

对不起,目前还没有std :: list和类似的容器。 (但是如果你真的需要它,你可以编写自己稍微不同的容器,并且仍然遵循STL接口的其余部分。)

但是,您不必使用默认的ctor:

std::list<CMyClass> listMyClass;
listMyClass.resize(1, obj_to_copy_from);

如:

std::list<CMyClass> listMyClass;
listMyClass.resize(1, CMyClass(use, specific, ctor));

调整大小如下:

void list<T>::resize(size_type new_size, T copy_from = T());

默认情况下,它会创建一个新对象(使用默认ctor)。

如果vector因为性能而允许在resize上使用默认构造函数初始化新元素,那将非常有用,但这不受支持。 如果你真的需要这个,实现自定义容器 - 没有别的办法。

使用指针或智能指针(boost :: shared_ptr而不是auto_ptr)

你可以在c11中做,对于旧版本,vesry simple可以改进

向量

myclas: public vector<A>
{
    push_back(Aconstructor_parameters)
    {
       new(_Mylast++) A(Aconstructor_parameters);
    }
};

使用时确保已使用reserve()分配内存

http://swagatata.tumblr.com/post/5896332725/vector-construction

即使你这样做

std::list<classname> objectname(100);

构造函数将被调用一次,并且将使用复制构造函数构造100个对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM