2015-07-01 3 views
3

Рассмотрим следующий код, в котором я пытаюсь ввести конструктор по умолчанию, а также параметризованный для class A. Этот способ был введен в последние улучшения C++.создание объекта: параметр по умолчанию против делегирования

class A { 
    private: 
     unsigned int count; 

    public: 
     A(int new_c) : count(new_c) {} 
     A() : A(10) {} 
}; 

vs старый способ установки параметра по умолчанию в параметризованный конструктор и полное игнорирование конструктора по умолчанию.

Есть ли какое-либо преимущество в использовании 1-го метода над вторым, кроме следующих современных конвенций?

+4

Для удобства использования это упрощенное, нет никакой реальной разницы. –

+3

Поскольку A() полностью не зависит от A (int), у него есть свое тело, где что-то конкретное может быть сделано после вызова A (int). –

+1

@ T.C. вы можете привести некоторые другие сложные варианты использования, которые могут показать любое преимущество/разницу. –

ответ

4

Хотя технически нет никакой разницы, идея создания экспедиционных конструкторов была другой. Представьте себе следующий класс:

class sample { 
    complexType member; 
    bool createdWithInt; 
public: 
    sample() : member(5), createdWithInt(false) { 
     /* code ... */ 
    } 
    sample(int param) : sample() { 
     createdWithInt = true; 
     /* other code */ 
    } 
}; 

Так этот класс трудно реализовать с параметрами по умолчанию: Его поведение не зависит от значения параметра, это скорее зависит от наличия.

Можно попытаться реализовать его с помощью вспомогательной функции void creator(), которая выполняет бит code ... от конструктора без аргументов. Однако это означало бы дублирование списка инициализации (или отказ от принципа RAII, если он инициализируется в пределах creator()).

Примечание: createdWithInt может быть инициализирован из списка инициализации, если был добавлен другой конструктор, который переводит bool и оба текущих конструктора вперёд к этому. Для примера это было опущено.

+0

... Конечно, на самом деле этот класс является кандидатом на полиморфную частную реализацию ...;) –

5

Функционально нет разницы. Знайте, что есть еще один вариант доступен с не-статической инициализации члена (так как C++ 11):

class A { 
    private: 
     unsigned int count = 10; 

    public: 
     A() = default; 
     A(int new_c) : count(new_c) {} 
}; 
4

Преимущество будет более заметным в случае большего класса, в котором может быть несколько конструкторов. По-новому вы сможете написать один конструктор, а затем установить его другим. Это меньше подвержено ошибкам.

class A { 
    private: 
     unsigned int count; 
     int other; 
     float otherfloat; 


    public: 
     A(unsigned int count, int other, float otherfloat) : count(count), other(other), otherfloat(otherfloat) {} 
     A(int new_c) : A(new_c, 0, 0.0) {} 
     A() : A(10) {} 
}; 
5

Там нет никаких преимуществ в том случае, как в вашем примере (я бы даже выбрать 2-й вариант, как более ясно, в таком примере)

Делегирование Конструкторов, где добавлено, чтобы облегчить работу, когда значения по умолчанию не было достаточно ,

Например

struct Point3d 
{ 
    Point3d(int x, int y, int z); 
    Point3d(Point2d p) : Point3d(p.x, p.y, 0) {} 
} 
Смежные вопросы