2011-04-06 30 views
0

我想这是没有这样一个聪明的问题,但我一直在花费大量的时间和仍然犯规编译虚函数

能否请您解释一下为什么?

感谢

1>------ Build started: Project: Ch17, Configuration: Release Win32 ------ 
1> p731.cpp 
1>\\na-13\agnolucp\my documents\visual studio 2010\projects\ch17\ch17\Bear.h(29): error  C2084: function 'std::ostream &Bear::print(std::ostream &) const' already has a body 
1>   \\na-13\agnolucp\my documents\visual studio 2010\projects\ch17\ch17\Bear.h(19) : see previous definition of 'print' 
1>p731.cpp(16): error C2264: 'Bear::print' : error in function definition or declaration; function not called 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 

//濒危

#ifndef ENDAGERED 
#define ENDAGERED 
#include <iostream> 


class Endangered { 
public: 
    //virtual ~Endangered(); 
    virtual std::ostream& print(std::ostream&) const; 
    // virtual so needs to be defined otherwise error 
    virtual void highlight() const; 
}; 

// ZooAnimal

#ifndef ZOOANIMAL 
#define ZOOANIMAL 
#include<string> 
class ZooAnimal { 
public: 
    ZooAnimal(); 
    ZooAnimal(std::string animal, bool exhibit, 
       std::string family): Name(animal), 
            OnExhibition(exhibit), 
            FamilyName(family) { } 
    //virtual ~ZooAnimal(); 

    virtual std::ostream& print(std::ostream&) const; 

    // accessors 
    std::string getName() const { return Name; } 
    std::string getFamilyName() const { return FamilyName; } 
    bool getOnExhibition() const { return OnExhibition; } 
    // ... 
protected: 
    std::string Name; 
    bool  OnExhibition; 
    std::string FamilyName; 
    // ... 
private: 
}; 

std::ostream& ZooAnimal::print(std::ostream &out) const { 
    return out << "I am printing ZooAnimal" << std:: endl; 
} 




#endif 




void Endangered::highlight() const { 
    std::cout << "HIGHLIGHT: HEY, I AM IN DANGER" << std::endl; 
} 


std::ostream& Endangered::print(std::ostream &out) const { 
    // thsi would be fine 
    // return out << "I Aa Printing Endangered" << std::endl; 
    out << "I Aa Printing Endangered" << std::endl; 
    return out; 
} 


#endif 

//熊

#ifndef BEAR 
#define BEAR 

#include "ZooAnimal.h" 
#include <iostream> 

class Bear : public ZooAnimal { 
enum DanceType { two_left_feet, macarena, fandango, waltz }; 
public: 
    Bear(); 
    //listing all arguments 
    // passing BaseClass constructor in initialiser list 
    Bear(std::string name, bool onExhibit=true, 
     std::string family = "Bear"): 
       ZooAnimal(name, onExhibit, family), 
       ival(0), dancetype(macarena) { } 

    virtual std::ostream& print(std::ostream&) const; 
    void dance() const; 

    //virtual ~Bear(); 
private: 
    int   ival; 
    DanceType dancetype; 
}; 
#endif 

std::ostream& Bear::print(std::ostream &out) const { 
    return out << "I am printing Bear" << std:: endl; 
} 

//熊猫

#ifndef PANDA 
#define PANDA 

#include <iostream> 
#include "Bear.h" 
#include"Endangered.h" 

class Panda : public Bear, public Endangered { 
public: 
    Panda(); 
    Panda(std::string name, bool onExhibit=true); 
    // virtual ~Panda(); 
    // mentioning virtual would not be necessary 
    virtual std::ostream& print(std::ostream&) const; 
    // mentioning virtual would not be necessary 
    virtual void highlight() const { 
     std::cout << "HIGHLIGHT: Hey I am Panda" <<std::endl; 
    } 
}; 


std::ostream& Panda::print(std::ostream &out) const { 
    // this would be fine 
    // return out << " I am printing Pandaa" << std::endl; 
    out << "I am printing Panda" << std::endl; 
    return out; 

} 


Panda::Panda(std::string name, bool onExhibit) 
     : Bear(name, onExhibit, "Panda") { } 

void Bear::dance() const { 
    switch(dancetype) { 
     case two_left_feet: 
      std::cout << "I am doing two_left_feet"<< std::endl; 
      break; 
     case macarena: 
      std::cout << "I am doing macarena"<< std::endl; 
      break; 
     case fandango: 
      std::cout << "I am doing fandango"<< std::endl;  
      break;   
     case waltz: 
      std::cout << "I am doing waltz"<< std::endl; 
      break; 
    } 
} 


# endif 

//勉

#include "Bear.h" 
#include "Panda.h" 
#include "ZooAnimal.h" 

#include<iostream> 
#include<string> 

int main() { 

    Endangered a; 
    ZooAnimal b("John", true, "DiMonte"); 
    //b.print(std::cout); 
    Bear c("Luigi"); 
    c.dance(); 
    c.print(std::cout); 
    Panda d("Luigi"); 
    d.print(std::cout); 
    d.highlight(); 
    d.dance(); 
    Panda e(); 
} 

回答

0

好愚蠢的答案是,你需要摆脱的

//#包括熊猫 “Bear.h”。

所以我的问题现在是 - 为什么? - 为什么我不需要包含#include“Bear.h”,因为Bear是我的继承层次结构的一部分?我认为编译器需要看到定义。

+0

的原因是,#ENDIF是以前 的std :: ostream的和熊:: print(std :: ostream&out)const { return out <<“我打印熊”<< std :: endl; } 所以它没有保护标题的多个内含物。愚蠢的我! – RandomCPlusPlus 2011-04-06 19:09:49

1

在main.cpp中你首先包含了Bear.h文件,并且这个文件包含了std :: ostream的定义:Bear :: print(std :: ostream & out)。这个定义不是由

#ifndef BEAR 
#define BEAR 
... 
#endif 

其次包括主守卫是Panda.h和Panda.h你再次包括Bear.h.并且因为你不能防范Bear :: print,所以它第二次被包含,并且编译器失败,因为它不知道它应该使用哪个方法定义。

为了减少这种错误的发生,你应该在你的* .h文件只声明,而所有的定义应该去*的.cpp

+0

感谢你 - 经过一番努力,我已经想出了自己的想法,但总是很高兴能够从别人那里得到你的想法的确认 – RandomCPlusPlus 2011-04-07 08:45:45