2012-04-12 3 views
2

Читаем Эффективное использование C++ (Scott Meyers) и получает ошибку «не подходят для оператора *» при попытке компиляции следующего кода из этой книги:нет матча для оператора *

rational.h

class rational 
{ 
    private: 
     int num; 
     int den; 
    public: 
     rational(int n = 0, int d = 1); 
     int getNum() const {return num;} 
     int getDen() const {return den;} 
}; 

rational.cpp

#include "rational.h" 

rational::rational(int n, 
        int d) 
    :num(n), 
    den(d) 
{} 

const rational operator*(const rational &lhs, 
         const rational &rhs) 
{ 
    return rational(lhs.getNum()*rhs.getNum(), 
         lhs.getDen()*rhs.getDen()); 
} 

main.cpp

#include "rational.h" 
int main() 
{ 
    rational r1(1,2); 
    rational r2; 
    r2 = 2*r1; 
    r2 = r1*3; 
    return 0; 
} 

Может кто-нибудь объяснить, почему это происходит?

+1

Вам нужно объявить 'operator *' в файле .h? Работает ли он, если вы поместите все классы и код в строку в main.cpp? – Rup

+0

Да, его компиляция в строке в main.cpp. Но почему ? –

+0

@Tony_M: Что касается того, как вы не знаете о декларациях и определениях, но реализуете операторы, константы и все: это даже ваш собственный код?/oops, вы ссылаетесь на Скотта Мейерса. Я думаю, что сначала вы должны получить вводную книгу, а не та, которая проявляет и обеспечивает ваши основные навыки. –

ответ

3

Вы не объявили operator* в своем файле заголовка, поэтому он не отображается в main.cpp.

5

Вы забыли рассказать пользователям о существовании вашего оператора:

rational.h

... 
const rational operator*(const rational &lhs, 
         const rational &rhs); 
... 

Как правило, в C, а также в C++, мы говорим о "определений" и «декларация». Объявления - это аннотации, чтобы сделать что-то видимым для кого-то другого, но сами по себе они ничего не делают. Определения являются entititiess, что на самом деле сделать что-то:

int foo();    // <- we call it "declaration" 
int foo() { return 0; } // <- we call it foo's "definition" 

В коде нет декларации operator* видимого в main.cpp, так что вам нужно предоставить один где-то (в идеале в вашем рациональны в заголовке).

Как советы стиль: Почти во всех случаях, если конструктор принимает встроенные типы, вы хотите сделать его явным:

explicit rational (int, int); 

Это предотвращает иногда тонкие ошибки, потому что (в вашем случае) rational s может быть непреднамеренно созданный (см. Automatic Conversions).

+0

+1 за то, что заставляю меня искать ключевое слово «Явное» http://stackoverflow.com/questions/121162/what-does-the-explicit-keyword-in-c-mean – Sogger

+2

@Sogger: будьте осторожны при поиске в Google «Явное» ключевое слово :( –

+0

@MooingDuck Ха-ха-ха! Вот почему ссылка, которую я разместил, была здесь, в SO. Поиск изображений Google: «Явный» = «Ядро паники»! Ошибка: 0x8000NSFW – Sogger

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