Каков предпочтительный способ инициализации аргументов по умолчанию конструктора? - PullRequest
0 голосов
/ 19 февраля 2019

Я видел следующие два способа инициализации аргументов в конструкторах по умолчанию (что также применимо и к обычным свободным функциям).

#include <string>
using UserDefinedType = std::string;

class MyClass
{
    UserDefinedType m_member;
public:
    // Way - 1
    MyClass(const UserDefinedType &obj = UserDefinedType()) : m_member{ obj } {}
    // Way - 2
    //MyClass(const UserDefinedType &obj = {}) : m_member{ obj }  {}
};
  • Я знаю, что первый вызов будет вызывать в обороне (явно)конструктор определенного пользователем типа.Что происходит вторым способом?
  • Что является предпочтительным способом практики с современными компиляторами (C ++ 11 или новее)?

1 Ответ

0 голосов
/ 19 февраля 2019

Это вопрос личных предпочтений, нет никакого влияния на то, что эти две опции делают или вызывают.Как я полагаю, здравый смысл состоит в том, чтобы повторно вводить типы, как в

const int three = static_cast<int>(3.14);
const Sub* sub = dynamic_cast<Sub*>(&baseInstance);

, который часто записывается с auto как

// better, the concrete type is only typed once, less maintainance "burden":
const auto three = static_cast<int>(3.14);
const auto* sub = dynamic_cast<Sub*>(&baseInstance);

, вы можете взять этот аргумент и передать егов приведенном выше фрагменте кода:

MyClass(const UserDefinedType &obj = UserDefinedType());

Здесь тип прописан дважды, и это нежелательно.Следовательно, я рекомендую перейти к

// Shorter, not less readable - a default-constructed default instance:
MyClass(const UserDefinedType &obj = {})

Обратите внимание, что в особом случае конструкторов одинаково просто использовать инициализацию члена класса вместе с конструктором по умолчанию и дополнительной перегрузкой, например

MyClass {
  public:
    MyClass() = default;
    explicit MyClass(const UserDefinedType& obj) : m_member{obj} {}

  private:
    UserDefinedType m_member = {};
};

Преимущество этого подхода заключается в низкой вероятности появления ошибок при добавлении новой перегрузки конструктора в класс.Но это нюанс.Однако обратите внимание, что я пометил ctor с одним аргументом explicit, который обычно считается хорошей практикой для предотвращения случайных неявных преобразований.

...