2014-10-08 4 views
1

Простите меня, если информация немного отсутствует, поскольку я стараюсь следовать рекомендуемым «Рекомендациям».Почему мой конструктор классов не инициализирует его переменные-члены?

Я создал класс под названием «Item» для хранения информации элемента и определили мой конструктор следующим образом:

Item::Item(std::string number, std::string name, int quantity, double price) { 
    itemNumber = number; 
    itemName = name; 
    quantity = quantity; 
    unitPrice = price; 
} 

и я инициализировать его в своей основной функции, как так:

Item temp("string", "string", 0, 0); 

но когда я печатал значения элемента, напечатано только itemNumber и itemName. Все, что напечатано, было случайным мусором. Тогда я понял, что проблема заключается в количестве, и цена не получает инициализации. Почему это?

+1

Пожалуйста, отправьте сообщение [MCVE] (http://stackoverflow.com/help/mcve) –

+2

Вы должны использовать уникальные имена переменных. Это также является одной из причин, по которым различные руководства по стилям предлагают префикс '' m_'' для переменных, которые являются переменными-членами, например. 'm_quantity = quantity' – CoryKramer

+0

О, ничего себе, это почти все. Не могу поверить, что я пропустил это. Благодаря! – Eddie

ответ

3

Попробуйте

this->quantity = quantity; 

или (ИМХО лучше):

Item::Item(const std::string& number, const std::string& name, int quantity_, double price) { 
                  //^
    // ... 
    quantity = quantity_; 
    // ... 
} 

или (ИМХО даже лучше) использовать список конструктор инициализатора:

Item::Item(const std::string& number, const std::string name&, int quantity, double price) 
: itemNumber(number), itemName(name), quantity(quantity), unitPrice(price) {} 

"Почему что?"

В настоящее время имя параметра изменяет имя переменной вашего члена в области тела конструктора.


Лично я, как правило, объявление классов нравится следующий

class Item { 
public: 
    Item(const std::string& number, const std::string& name, int quantity, double price) 
    : itemNumber_(number) 
    , itemName_(name) 
    , quantity_(quantity) 
    , unitPrice_(price) {} 
private: 
    std::string itemNumber_; 
    std::string itemName_; 
    int quantity_; 
    double unitPrice_ 
}; 
+1

Зачем добавлять '_' к одному параметру, а не к другому, это непротиворечиво. –

+0

@NeilKirk Ну, остальные не затеняют имена переменных-членов. Будет путать больше, чем прояснить ИМХО. –

+0

Почему бы вам не дать члену класса '_' postfix вместо параметра, как вы указываете в вопросительном комментарии? Я считаю, что это сделает его более последовательным и менее запутанным. – Kaiged

0

quantity = quantity; И здесь относятся к параметру, а не переменный член. Чтобы обратиться к переменной-члена внутри функции, которая имеет параметр с тем же именем, вы должны использовать этот указатель, например this->quantity = quantity; или же квалифицировать его с именем класса, например Item::quantity = quantity;

Также можно использовать список инициализации, чтобы избежать этого проблемы и, возможно, более эффективно инициализировать ваш класс.

Item::Item(const std::string& number, const std::string& name, int quantity, double price) 
: itemNumber(number) 
, itemName(name) 
, quantity(quantity) 
, price(price) 
{ 
} 

Я взял на себя смелость сделать ваши строковые параметры const ссылкой, чтобы избежать копирования.

+0

, но вы делаете копию, делая' itemNumber (number), itemName (name) 'anyway. Вы просто переносите копию в другое место и затрудняете оптимизацию компилятора. –

+0

@MattMcNabb Возможно, в C++ 11, я не уверен, но не в старом C++. И любая микро-оптимизация, включающая строку с распределением кучи, будет незначительной. Константы никогда меня не подводили. Const ссылки сделали мне хорошо. –

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