Reputation: 359
I suppose it is not such a clever question but i have been spending considerable time on it and still doesnt compile
Can you please explain why?
Thanks
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 ==========
//Endangered
#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
// Bear
#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;
}
// panda
#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
// mian
#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();
}
Upvotes: 0
Views: 461
Reputation: 2640
In main.cpp you firstly included Bear.h and this file contains definition of std::ostream& Bear::print(std::ostream &out). This definition is not guarded by
#ifndef BEAR
#define BEAR
...
#endif
Second include in main is Panda.h and in Panda.h you once again include Bear.h. And because you don't guard Bear::print it is included second time and compiler fails because it doesn't know which method definition it should use.
To reduce occurrence of such errors you should include only declaration in your *.h files while all definitions should go to *.cpp
Upvotes: 1
Reputation: 359
Ok the stupid answer is that you need to get rid of
//#include "Bear.h" in Panda.
so my question is now - why? - why dont I need to include #include "Bear.h" as Bear is part of my inheritance hierarchy? I thought the compiler needed to see the definition.
Upvotes: 0