2012-04-12 39 views
2

我读的有效C++(斯科特迈尔斯),并试图从本书编译下面的代码时收到错误“无匹配的运算符*”:敌不过运算符*

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

您是否需要在.h文件中声明'operator *'?如果你把所有的类和代码放入main.cpp中,它会起作用吗? – Rup 2012-04-12 15:35:45

+0

是的,它在main.cpp中编译内联。但为什么 ? – 2012-04-12 15:38:55

+0

@Tony_M:关于你如何不知道声明和定义,还要实现运算符,常量和所有:这是否甚至是你自己的代码?/oops,你是指Scott Meyers。我认为你应该首先得到一本介绍性的书,而不是一个体现和强化你的基本技能的书。 – 2012-04-12 15:57:39

回答

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" 

在你的代码,也没有在main.cpp中operator*可见的声明,所以你需要提供一个地方(最好是在你理性的头)。

作为一种风格的建议:在几乎所有情况下,如果一个构造函数采用内建类型,你想让它明确:

explicit rational (int, int); 

这可以防止有时微妙的错误,因为(在你的情况下)rational S可能会发生是无意中创建(见Automatic Conversions)。

+0

+1让我查找'显式'关键字http://stackoverflow.com/questions/121162/what-does-the-explicit-keyword-in-c-mean – Sogger 2012-04-12 16:36:34

+2

@Sogger:非常谨慎Google搜索'显式'关键字:( – 2012-04-12 21:32:26

+0

@MooingDuck哈哈哈!这就是为什么我发布的链接是在这里。谷歌图片搜索:'显式'=内核恐慌!错误:0x8000NSFW – Sogger 2012-04-13 14:56:34