Newbie C++ Question

D

Dave

Hi All,

I have a question regarding using multiple CPP source files.

I have a class, "Mammal.cpp" that contains different member variables and
functions. I now want to create several classes, each in its own source
file, that use "Mammal" as a base class. What's the best way of doing this?
If I #include the entire "Mammal.cpp" file into my new classes the compile
works....but I don't think that this would be considered a Best Practice.

I've seen examples in C where people create a Header file and place variable
and function declarations in it. Does it work the same way in C++? Do I
simply copy "Mammal.cpp" to "Mammal.h" and then delete the implementation
(leaving just the Class declarations)? Assuming this is my base class,
"Mammal.cpp":

class Mammal {
private:
int age;

public:
int getAge() {return age; }
void setAge(int x) { age = x; }

Mammal::Mammal(int x) {
age = x;
}

};

What would the "Mammal.h" file contain?

Thanks in advance.
 
V

Victor Bazarov

Dave said:
I have a question regarding using multiple CPP source files.

I have a class, "Mammal.cpp" that contains different member variables and
functions. I now want to create several classes, each in its own source
file, that use "Mammal" as a base class. What's the best way of doing this?
If I #include the entire "Mammal.cpp" file into my new classes the compile
works....but I don't think that this would be considered a Best Practice.

I've seen examples in C where people create a Header file and place variable
and function declarations in it. Does it work the same way in C++?

Yes. What book on C++ are you reading that doesn't explain that?
Do I
simply copy "Mammal.cpp" to "Mammal.h" and then delete the implementation
(leaving just the Class declarations)?

It looks like it, judging from the contents of your 'Mammal.cpp'.
Assuming this is my base class,
"Mammal.cpp":

class Mammal {
private:
int age;

public:
int getAge() {return age; }
void setAge(int x) { age = x; }

Mammal::Mammal(int x) {
age = x;
}

};

What would the "Mammal.h" file contain?

Essentially you already have it. I'd only add "double inclusion guards":
---------------------------- Mammal.h
#ifndef MAMMAL_H_INCLUDED
#define MAMMAL_H_INCLUDED

....here you put all the stuff...

#endif
 
D

Dave

Thanks for your response, Victor.

I'm actually working on a project to convert some old legacy C/370 mainframe
code to C++ under Z/OS. I used the "mammal" analogy to keep things simple.
I have access to more online technical books than I'll ever have time to
read so I'm putting things together on the fly. ;-)

Just to clarify, using the "mammal" example, I should put the entire class
in a "Mammal.h" file and add double inclusion safeguards? Following this
line of thought, should I do the same for all classes that use mammal as a
base class?

eg. "dog.h" would look like this:
------------------------------------
#include <Mammal.h>

#ifndef DOG_H_INCLUDED
#define DOG_H_INCLUDED

class Dog: Public Mammal {

...class implementation here

};
#endif
------------------------------------

....if I then wanted to create a "MammalFactory" object, I'd then code
something like this?....

#include <Dog.h>
#include <Cat.h>
#include <Cow.h>

class MammalFactory {
....
};

void main() {
//DOG is a constant that tells getMammal() to return a Dog object
Mammal fluffy = MammalFactory.getMammal(DOG);
}

Does this look reasonably correct? I'm a little confused because I read
somewhere that implementation details (and I assumed that to mean class
implementations) do not belong in Header files. I guess I can throw the
entire class implementation into a header file and simple #include as
required.

Thanks again!
 
E

E. Robert Tisdale

Dave said:
I have a question regarding using multiple source files.

I have a class Mammal that contains different data members.
I now want to create several classes, each in its own [header] file.
that use "Mammal" as a base class.
What's the best way of doing this?
If I #include the entire "Mammal.cpp" file into my new classes,
the compile works
but I don't think that this would be considered a Best Practice.

Best practice is to split each *module* up into
an *interface* (header file) and
one or more *implementation* (source file).
I've seen examples in C where people create a header file
and place variable and function declarations in it.
Does it work the same way in C++?
Yes.

Do I simply copy "Mammal.cpp" to "Mammal.h" and then delete the implementation
(leaving just the Class declarations)? Assuming this is my base class,
"Mammal.cpp":

class Mammal {
private: // representation
int age;

public:
int getAge(void) { return age; }
void setAge(int x) { age = x; }

This should be

Mammal& setAge(int x) {
age = x;
return *this;
}

so that it can be used in an expression.
Mammal::Mammal(int x): age(x) { }

Use an initialization list instead of assignment in constructors.
};

What would the "Mammal.h" file contain?

Your header file should be both

1. self-sufficient and
2. idempotent.

Self sufficient means that it includes any header files
required to process your header file and idempotent means
that the contents will be processed *exactly* once.
The guard macros ensure that the header is idempotent.
cat Mammal.h
#ifndef GUARD_MAMMAL_H
#define GUARD_MAMMAL_H 1

class Mammal {
private:
// representation
int age;
public:
// functions
int getAge(void) { return age; }
Mammal& setAge(int x) {
age = x;
return *this;
}
// constructors
explicit
Mammal::Mammal(int x): age(x) { }
};

#endif//GUARD_MAMMAL_H
cat Mammal.cpp
#include "Mammal.h"

In this case, Mammal.cpp is empty
except for the included header file
but this is where you would place any
*external* function definitions
for functions declared but *not* defined
in the Mammal.h header file.
 
J

jeffc

Dave said:
Hi All,

I have a question regarding using multiple CPP source files.

I have a class, "Mammal.cpp" that contains different member variables and
functions.

Not to be pedantic, but that's a file. Presumably inside that file is a class
called Mammal.
I now want to create several classes, each in its own source
file, that use "Mammal" as a base class. What's the best way of doing this?
If I #include the entire "Mammal.cpp" file into my new classes the compile
works....but I don't think that this would be considered a Best Practice.

I've seen examples in C where people create a Header file and place variable
and function declarations in it. Does it work the same way in C++?
Yes.

Do I
simply copy "Mammal.cpp" to "Mammal.h" and then delete the implementation
(leaving just the Class declarations)?

Yes (*remove* the declarations from the .cpp file, and add them to the .h or
..hpp file.)
Assuming this is my base class,
"Mammal.cpp":

class Mammal {
private:
int age;

public:
int getAge() {return age; }
void setAge(int x) { age = x; }

Mammal::Mammal(int x) {
age = x;
}

};

What would the "Mammal.h" file contain?

Well, technically what you've done will work but it's confusing because you've
used implied inlining. In your header file goes
class Mammal {
private:
int age;

public:
int getAge();
void setAge(int x);
}
};

Get in the habit of removing implementation from your declarations, at least for
now until you've got this all figured out.
 
V

Victor Bazarov

Dave said:
[...]
Just to clarify, using the "mammal" example, I should put the entire class
in a "Mammal.h" file and add double inclusion safeguards?
Yes.

Following this
line of thought, should I do the same for all classes that use mammal as a
base class?
Probably.

eg. "dog.h" would look like this:
------------------------------------
#include <Mammal.h>

#ifndef DOG_H_INCLUDED
#define DOG_H_INCLUDED

I'd move the #include said:
class Dog: Public Mammal {

...class implementation here

};
#endif
------------------------------------

...if I then wanted to create a "MammalFactory" object, I'd then code
something like this?....

#include <Dog.h>
#include <Cat.h>
#include <Cow.h>

class MammalFactory {
...
};

void main() {

int main() {
//DOG is a constant that tells getMammal() to return a Dog object
Mammal fluffy = MammalFactory.getMammal(DOG);
}

Does this look reasonably correct?
Sure.

I'm a little confused because I read
somewhere that implementation details (and I assumed that to mean class
implementations) do not belong in Header files.

That's up to you. The compiler doesn't really care in this particular
case. If you want to reduce the number of files you need to recompile
when you change the implementation of a particular member function, it
would be better to keep the _implementation_ in a C++ _source_, while the
class definitions with declarations only should be kept in the headers.

These are really very basic things about organising your project and you
probably should take some time off coding to learn a thing or two about
this. And, believe me, it's better to learn from a trusted source like
a book from a reputable author, than from a newsgroup thread.
I guess I can throw the
entire class implementation into a header file and simple #include as
required.
Yep.

[...]

V
 
J

jeffc

Dave said:
...if I then wanted to create a "MammalFactory" object, I'd then code
something like this?....

#include <Dog.h>
#include <Cat.h>
#include <Cow.h>

class MammalFactory {
...
};

void main() {
//DOG is a constant that tells getMammal() to return a Dog object
Mammal fluffy = MammalFactory.getMammal(DOG);
}

Does this look reasonably correct?
Yes.

I'm a little confused because I read
somewhere that implementation details (and I assumed that to mean class
implementations) do not belong in Header files. I guess I can throw the
entire class implementation into a header file and simple #include as
required.

Right. See my other post. You should take all that implementation out of the
header file and leave it in the .cpp file.
For example, in the .cpp will be

//constructor has no return type specified
Mammal::Mammal(int x)
{
age = x;
}
void Mammal::setAge(int x)
{
age = x;
}
int Mammal::getAge()
{
return age;
}
By the way there is a better way to write your constructor but we can get to
that later.
 
V

Victor Bazarov

jeffc said:
Not to be pedantic, but that's a file. Presumably inside that file is a class
called Mammal.

Why do you call it "not to be pedantic"? I always thought that such
nit-picking is exactly what makes a pedant (in a good sense of the word).
[...]
What would the "Mammal.h" file contain?


Well, technically what you've done will work but it's confusing because you've
used implied inlining. In your header file goes
class Mammal {
private:

'private:' is superfluous. To be pedantic, that is.
int age;

public:
int getAge();
void setAge(int x);
}

Extraneous curly brace, or so it seems.
};

Get in the habit of removing implementation from your declarations, at least for
now until you've got this all figured out.

To be pedantic, it's "removing implementation from class definitions".

V
 
E

E. Robert Tisdale

jeffc said:
Well, technically, what you've done will work
but it's confusing because you've used implied inlining.
In your header file goes

class Mammal {
private:
int age;

public:
int getAge(void);
Mammal& setAge(int x);
Mammal(int x);
};

inline
int Mammal::getAge(void) {
return age;
}

inline
Mammal& Mammal::setAge(int x) {
age = x;
return *this;
}

inline
Mammal::Mammal(int x): age(x) { }
Get in the habit of removing implementation from your declarations,
at least for now until you've got this all figured out.

You probably meant something like
"Get in the habit of separating member function definitions
from member function declarations in your class definition ..."
 
J

jeffc

Victor Bazarov said:
Why do you call it "not to be pedantic"? I always thought that such
nit-picking is exactly what makes a pedant (in a good sense of the word).

Well, you've got me there. I should have said "not to be pedantic in an
annoying way, I hope, but..."
'private:' is superfluous. To be pedantic, that is.

Maybe so, but it's also explicit, which I prefer.
Extraneous curly brace, or so it seems.

No, I think you're just looking out of context.
To be pedantic, it's "removing implementation from class definitions".

Stroustrup sez: it's "called a class definition because it defines a new type.
For historical reasons, a class definition is often referred to as a class
declaration." I felt that in this context (removing implementation from a
definition), given my understanding of the OP's experience, level, "declaration"
got my meaning across more clearly to him.
 
J

jeffc

E. Robert Tisdale said:
You probably meant something like
"Get in the habit of separating member function definitions
from member function declarations in your class definition ..."

Yes, except as explained in my other post, I used "class declaration" for a
reason in this context.
 
J

jeffc

E. Robert Tisdale said:
Your header file should be both

1. self-sufficient and
2. idempotent.

Self sufficient means that it includes any header files
required to process your header file and idempotent means
that the contents will be processed *exactly* once.

Wow, that is quite a word - idempotent. But anyway, those are wise words and
will save you gnashing of teeth in the future.
In this case, Mammal.cpp is empty
except for the included header file
but this is where you would place any
*external* function definitions
for functions declared but *not* defined
in the Mammal.h header file.

I think that's very confusing at this point, and for better understanding I'd
highly recommend not using any implicit inline functions right now.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,270
Latest member
TopCryptoTwitterChannels_

Latest Threads

Top