Перегрузка явного конструктора в C ++ - PullRequest
0 голосов
/ 11 июня 2018

Я читаю книгу и получил некоторый код для проектирования классов, который я не совсем понимаю.

class Queue {
public:
    Queue(size_t capacity) {}
    explicit Queue(int capacity) : entries_(capacity) {}
...
private:
    vector<int> entries_;
...
};

И еще один подобный,

class LruCache {
public:
    LruCache(size_t capacity) {}
    explicit LruCache(int capacity) : capacity_(capacity) {}
...
private:
    int capacity_;
...
};

У меня есть два вопроса,

  1. Можем ли мы перегружать методы исключительно по ключевому слову explicit, например по ключевому слову const?В моем случае тип аргумента немного отличается: int и size_t.

  2. Более важный вопрос - почему.Зачем нам перегруженный explicit конструктор?Я полагаю, что в праймере C ++ перегрузка функций с аналогичными типами аргументов не рекомендуется.

edit:

Мой 2-й вопрос больше о фрагменте кода выше.Почему у него есть конструктор с аргументом int, а затем конструктор explicit с аргументом size_t, а int и size_t являются типами, которые действительно близки.Поэтому не должно быть необходимости определять два конструктора для каждого из них.Я полагаю, что автор определяет два конструктора по определенной причине, но я не знаю почему, и это должно быть моим вторым вопросом.Не общий вопрос о том, что делает ключевое слово explicit.К сожалению.

1 Ответ

0 голосов
/ 11 июня 2018

Можем ли мы перегружать методы только по ключевому слову explicit

Нет.

Зачем нам нужен перегруженный явный конструктор?

Чтобы избежать неявных преобразований.

Допустим, Queue был определен как:

class Queue {
  public:
    // No constructor with a size_t.
    Queue(int capacity) {}
  ...
};

При этом int будет неявно преобразован в Queueпри необходимости.

void bar(Queue const& q) { ... }

bar(10); // This would be valid without the explicit keyword.
         // 10 will be implicitly converted to Queue(10).

Иногда такие неявные преобразования приводят к сложному пониманию и поддержанию кода.Чтобы избежать таких неявных преобразований, используется квалификатор explicit.

С установленным квалификатором explicit вам потребуется использовать

bar(Queue(10));

, что намного прощепонять.

Почему у него есть конструктор с аргументом size_t, а затем конструктор explicit с аргументом int,

Не знаюувидеть любую причину, по которой вам понадобятся две перегрузки - explicit или нет.Если в книге не объясняется, зачем они нужны, мы можем объяснить это только отсутствием ясности со стороны автора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...