Предпочтительная передача параметров для конструкторов - PullRequest
2 голосов
/ 04 октября 2011

Есть ли предпочтительная практика для передачи параметров конструктора?В частности, если эти параметры конструктора используются для инициализации переменных-членов.

Упрощенный пример.

class Example
{
public:
   Example( /*type-1*/ str, /*type-2*/ v ):
      m_str( str ),
      m_v( v )
   { }

   /* other methods */

private:
   std::string m_str;
   std::complex<float> m_v;
};

Возможны следующие варианты:

  • передача по значению, затем std::move объект в элемент.
  • const&, затем скопируйте параметр в элемент.
  • &&, затем инициализируйте элемент с параметром.

Каким должен быть мой стиль передачи параметров по умолчанию / предпочтительный?
Меняется ли он в зависимости от типа параметра?

Моя интуиция говорит, что используются ссылки на rvalue, но я не уверен, что понимаювсе плюсы и минусы.

1 Ответ

6 голосов
/ 04 октября 2011

Вариант 1:

class Example
{
public:
   Example( std::string str, const std::complex<float>& v ):
      m_str( std::move(str) ),
      m_v( v )
   { }

   /* other methods */

private:
   std::string m_str;
   std::complex<float> m_v;
};

Это имеет довольно хорошую производительность и легко кодируется. Единственное место, где оно немного не соответствует оптимальному, - это когда вы привязываете lvalue к str. В этом случае вы выполняете как конструкцию копирования, так и конструкцию перемещения. Оптимальным является только копирование конструкции. Обратите внимание, что конструкция перемещения для std::string должна быть очень быстрой. Поэтому я бы начал с этого.

Однако, если вам действительно нужно извлечь из этого последние циклы для повышения производительности, вы можете сделать:

Вариант 2:

class Example
{
public:
   Example( const std::string& str, const std::complex<float>& v ):
      m_str( str ),
      m_v( v )
   { }
   Example( std::string&& str, const std::complex<float>& v ):
      m_str( std::move(str) ),
      m_v( v )
   { }

   /* other methods */

private:
   std::string m_str;
   std::complex<float> m_v;
};

Основным недостатком этой опции является перегрузка / репликация логики конструктора. Действительно, эта формула станет нереальной, если у вас есть более одного или двух параметров, которые необходимо перегрузить между const& и &&.

...