-
December 5th, 2003, 03:45 PM
#1
completely a newbie question - about cpp/hpp files
As I started to use C++ this tuesday, I did not know anything about it. For now, I tought I should do all the code like:
Code:
// file: Foo.cpp
#ifndef INCLUDED_FOO
#define INCLUDED_FOO
#include <string>
using namespace std;
class Foo
{
private:
string s;
public:
virtual ~Foo() {}
virtual void print()
{
cout<<"foo";
}
};
#endif
--------
// file: Bar.cpp
#ifndef INCLUDED_BAR
#define INCLUDED_BAR
#include <string>
using namespace std;
#include "Foo.cpp"
class Bar : public Foo
{
private:
string g;
public:
virtual ~Bar() {}
void print()
{
cout<<"bar";
}
};
#endif
ok, I realized that I have to split the code into hpp and cpp files.
Well I tried the following, but the gcc compiler prompts about
virtual outside class declaration...
Code:
// foo.hpp
#ifndef INCLUDED_FOO_HPP
#define INCLUDED_FOO_HPP
class Foo
{
private:
string s;
public:
virtual ~Foo() {}
virtual void print();
};
#endif
-----
// foo.cpp
#include <string>
using namespace std;
#include "Foo.hpp"
virtual Employee::~Employee() {}
virtual void Employee::print()
{
cout<<"foo";
}
What I`m missing here?
-
December 5th, 2003, 03:53 PM
#2
You cannot put "virtual" in the .cpp file. Remove it and it should compile.
Also, never put "using namespace <anything>" in a header file. It forces everybody that includes that file to use that namespace.
Jeff
-
December 5th, 2003, 03:57 PM
#3
You're not missing... you've added something. The "virtual" keyword only gets placed inside the class declaration (the part that gets put in the header). The implementation of the various function definitions do not need (nor can they, according to the language) to tell the compiler anything about it being virtual (since that translation unit already knows by including the header and all other translation units have that same information so they can compile for dynamic binding).
*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
"It's hard to believe in something you don't understand." -- the sidhi X-files episode
galathaea: prankster, fablist, magician, liar
-
December 5th, 2003, 04:00 PM
#4
Don't include c, cc, or cpp files EVER.
Don't do it.
-
December 5th, 2003, 04:08 PM
#5
Hi again,
I tried, but no luck
Code:
#ifndef INCLUDED_ANIMAL_HPP
#define INCLUDED_ANIMAL_HPP
class Animal
{
protected:
string name;
string colour;
string breed;
public:
// virtual destructor to make derived classes virtual
virtual ~Animal() {}
virtual void setName(string nam);
virtual string getName();
virtual void setColour(string c);
virtual string getColour();
// help function
virtual void clearBuffer(char chars[] ,int len);
virtual void setBreed(string g) = 0;
virtual string getBreed() = 0;
virtual void serialize(ofstream& file) = 0;
virtual void deSerialize(ifstream& file) = 0;
};
#endif
Code:
#include <string>
#include <fstream>
using namespace std;
#include <string>
#include "Animal.hpp"
Animal::~Animal() {}
void Animal::setName(string name)
{
name = nam;
}
string Animal::getName()
{
return name;
}
void Animal::setColour(string c)
{
colour = c;
}
string Animal::getColour()
{
return colour;
}
void Animal::clearBuffer(char chars[] ,int len)
{
for(int i = 0; i < len; i++)
chars[i] = ' ';
}
void Animal::setBreed(string b) = 0;
string Animal::getBreed() = 0;
void Animal::serialize(ofstream& file) = 0;
void Animal::deSerialize(ifstream& file) = 0;
The output when I compile:
Code:
C:\projects\animal>gcc -c -Wall Animal.cpp
Animal.cpp:13: redefinition of `Animal::~Animal()'
Animal.hpp:18: `virtual Animal::~Animal()' previously defined here
Animal.cpp: In member function `virtual void
Animal::setName(std::basic_string<char, std::char_traits<char>,
std::allocator<char> >)':
Animal.cpp:17: `nam' undeclared (first use this function)
Animal.cpp:17: (Each undeclared identifier is reported only once for each
function it appears in.)
Animal.cpp: At global scope:
Animal.cpp:41: function `virtual void Animal::setBreed(std::basic_string<char,
std::char_traits<char>, std::allocator<char> >)' is initialized like a
variable
Animal.cpp:41: declaration of `virtual void
Animal::setBreed(std::basic_string<char, std::char_traits<char>,
std::allocator<char> >)' outside of class is not definition
Animal.cpp:43: function `virtual std::string Animal::getBreed()' is initialized
like a variable
Animal.cpp:43: declaration of `virtual std::string Animal::getBreed()' outside
of class is not definition
Animal.cpp:45: function `virtual void Animal::serialize(std::ofstream&)' is
initialized like a variable
Animal.cpp:45: declaration of `virtual void Animal::serialize(std::ofstream&)'
outside of class is not definition
Animal.cpp:47: function `virtual void Animal::deSerialize(std::ifstream&)' is
initialized like a variable
Animal.cpp:47: declaration of `virtual void
Animal::deSerialize(std::ifstream&)' outside of class is not definition
...not a clue ....
-
December 5th, 2003, 04:17 PM
#6
You are providing a body more than once.
In the header, instead of:
Code:
virtual ~Animal() {}
you should have
Jeff
-
December 5th, 2003, 04:25 PM
#7
ah, one error message removed!
But it did not affect to the rest...
-
December 5th, 2003, 04:33 PM
#8
ah, got it!
Those virtual functios should not be in the cpp file ... works fine!
Thanks again !!
-
December 5th, 2003, 04:55 PM
#9
In your Animal class, you made EVERY function virtual,
even the "get" and "set" functions (setName(),getName() etc.)
I don't think that you really want those functions redefinable
in derived classes, so I would make them non-virtual. Of
course, if you do want them to be redefianble in derived
classes, then keep them virtual.
Also, look at the argugment in your setName() (and oher set
functions). It is "string nam". You are passing the string
variable by value, which causes a copy to be made. This
can be somewhat inefficent. For these types of functions,
you should pass by const reference. This makes it so
a copy does not have to be made, but still prevents
the function from modifying the argument.
Code:
void Animal::setName(const string& name) // change in header also
{
//...
}
Last edited by Philip Nicoletti; December 5th, 2003 at 05:18 PM.
-
December 8th, 2003, 07:12 PM
#10
I see a lot of errors, some of which have been addressed.
Basically, class declarations go into a .hpp file (or .h or .hxx)
The body code of a class goes into a .cpp file (or .cxx)
The exception is templates, where everything must go into one file.
In addition, there are occasions where you will inline all the code of a class within its header file, and there are other classes which may occasionally be defined within a source file, particularly functor classes when you get advanced enough to use them.
But best to stick for now with the rule of .hpp files showing class prototypes only.
One thing you should become accustomed to (best to start with good habits) is to pass const string & as parameters rather than string. Passing as a string parameter works but is less efficient.
-
December 9th, 2003, 04:38 AM
#11
Hi NMTop40, long time no see.
A general rule for splitting between header and implementation files:
The header file contains only what you want the rest of the program to know about. The implementation file contains everything else.
Corollary: give the rest of the program the minimum amount of information necessary to use your class.
Sometimes, of course, you have to give more away (template classes for example), but in general your attitude should be to hide as much as possible - that way, changes that you make to your implementation have less efect on the rest of the program.
Look up the pimpl idiom for a prime example of hiding implementation.
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
-- Sutter and Alexandrescu, C++ Coding Standards
Programs must be written for people to read, and only incidentally for machines to execute.
-- Harold Abelson and Gerald Jay Sussman
The cheapest, fastest and most reliable components of a computer system are those that aren't there.
-- Gordon Bell
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|