2010-05-17 2 views
4

К концу главы 16 «++ Primer С» я столкнулся следующий код (я удалил кучу строк):Constructor список инициализации: Код с ++ Primer C, глава 16

class Sales_item { 
public: 
    // default constructor: unbound handle 
    Sales_item(): h() { } 
private: 
    Handle<Item_base> h; // use-counted handle 
}; 

Моя проблема связана с линией Sales_item(): h() { }.

Для полноты картины, позвольте мне процитировать части шаблона класса ручки, которые я думаю, имеют отношение к моему вопросу (я думаю, что мне не нужно, чтобы показать класс Item_base):

template <class T> class Handle { 
public: 
    // unbound handle 
    Handle(T *p = 0): ptr(p), use(new size_t(1)) { } 
private: 
    T* ptr;   // shared object 
    size_t *use;  // count of how many Handles point to *ptr 
}; 

я ожидал бы что-то вроде как:

а) Sales_item(): h(0) { } которое конвенции авторы использовали неоднократно в предыдущих главах, или

б) Handle<Item_base>() если намерение было вызвать конструктор по умолчанию класс Handle.

Вместо этого у книги есть Sales_item(): h() { }. Моя реакция кишки заключается в том, что это опечатка, так как h() выглядит подозрительно похожей на объявление функции. С другой стороны, я просто попытался скомпилировать под g ++ и запустить код примера, который использует этот класс, и, похоже, работает правильно. Есть предположения?

EDIT: Все хорошие ответы, спасибо! В промежуточные 30 минут я проследил соответствующую цитату из главы 12 той же книги: «Когда мы инициализируем члена типа класса, мы указываем аргументы, которые должны быть переданы одному из конструкторов этого типа члена. Мы можем использовать любой из конструкторов этого типа. " И, как вы все указывали, в этом случае мы передаем нулевые аргументы.

ответ

6

Что вы имеете с Sales_item(): h() { } является конструктором с инициализацией элемента данных.

я ожидал бы что-то вроде как:

а) Sales_item(): h(0) { } который является условность авторы использовали неоднократно в предыдущих главах, или

Это не является необходимым, так как конструктор Handle<Item_base>() может быть вызван без аргумента. (Его один аргумент имеет значение по умолчанию, так что он может быть опущен.)

б) Handle<Item_base>(), если целью было вызвать конструктор по умолчанию класса ручки.

Это просто неправильный синтаксис. Этот синтаксис используется для базовых классов, и там это прекрасно, так как любой класс может наследовать только один раз от Handle<Item_base>(). Однако он может иметь много элементов данных этого типа, поэтому для инициализации нужного элемента данных его имя используется, а не его тип.


Это очень хорошая книга, которую вы изучаете, BTW. После того, как вы пройдете через него, вы можете посмотреть на The Definitive C++ Guide and List для получения более хорошего ввода.

+0

Вы абсолютно правы в точке b. Из моих правлений видно, что я не совсем уверен, с чем это связано. –

1

h это имя переменной члена Sales_item, и его класс Handle имеет конструктор с параметром по умолчанию, так h() строит элемент правильно. Это эквивалентно h(0).

2

Код полностью верный - средство h() использует конструктор по умолчанию для построения h. В этом случае это также необязательно, поскольку конструктор по умолчанию будет использоваться, если вы не дадите явную инициализацию. Конструктор по умолчанию - это любой конструктор, который может быть вызван без аргументов, который имеет класс handle из-за его значения аргумента по умолчанию.

Смежные вопросы