.h and .cpp

C

Christopher

If you were on a team of developers that had little C++ experience,
how would you go about explaining the reasoning as to why the
following rules should be followed? (Or why they shouldn't)

1) Class defintions go in their own .h (or .hpp for templates) file
named after the class
1a) Every class should have its own .h (or .hpp for templates) file
1b) A .h file should never contain class implementation (except for
inline functions or methods)

2) Class implementations go in their own .cpp file (except for
templates)
2a) A .cpp should never contain a class definition

3) One should not define multiple classes in a single .h file
3a) Nested class defintions should be avoided without good reason
(what's good reason?)

6) Variables should never be defined in a .h file
7) Globals should not be defined in a .h file
8) Every .cpp file should compile into a .obj file without error or
warning on its own.
i.e In Visual Studio, you should be able to right click a .cpp in
the source tree and choose compile, without error or warning in the
output.
----

Sadly, I find myself having to justify these things. (of course
someone might point out I am wrong or exceptions to the above), but
these are things that I've always had drilled into my head throughout
the years and have rarely come acorss other developers that didn't do
the same. I am finding it frustrating to work on a project where 30
classes defintions reside in the .h same .h file, a single .cpp file,
or worse a precompiled header. There is discussion, but I have to
explain reasoning.

So far, I've come up with the testability argument:
When unit testing one frequently wants to test a single class. A proxy
class may need to be created to test its protected or privare methods.
Proxies may have to be created for its input and outputs. I should be
able to include a single .h file, link in the appropriate .obj files
and compile a unit test without the added clutter of satisfying
includes or linkage needed by unrelated classes.

I don't know what else to say aside from, "just do it, its the thing
to do." and noone is going to buy that.
 
R

ralph

If you were on a team of developers that had little C++ experience,
how would you go about explaining the reasoning as to why the
following rules should be followed? (Or why they shouldn't)

1) Class defintions go in their own .h (or .hpp for templates) file
named after the class
1a) Every class should have its own .h (or .hpp for templates) file
1b) A .h file should never contain class implementation (except for
inline functions or methods)

2) Class implementations go in their own .cpp file (except for
templates)
2a) A .cpp should never contain a class definition

3) One should not define multiple classes in a single .h file
3a) Nested class defintions should be avoided without good reason
(what's good reason?)

6) Variables should never be defined in a .h file
7) Globals should not be defined in a .h file
8) Every .cpp file should compile into a .obj file without error or
warning on its own.
i.e In Visual Studio, you should be able to right click a .cpp in
the source tree and choose compile, without error or warning in the
output.
----

Sadly, I find myself having to justify these things. (of course
someone might point out I am wrong or exceptions to the above), but
these are things that I've always had drilled into my head throughout
the years and have rarely come acorss other developers that didn't do
the same. I am finding it frustrating to work on a project where 30
classes defintions reside in the .h same .h file, a single .cpp file,
or worse a precompiled header. There is discussion, but I have to
explain reasoning.

So far, I've come up with the testability argument:
When unit testing one frequently wants to test a single class. A proxy
class may need to be created to test its protected or privare methods.
Proxies may have to be created for its input and outputs. I should be
able to include a single .h file, link in the appropriate .obj files
and compile a unit test without the added clutter of satisfying
includes or linkage needed by unrelated classes.

I don't know what else to say aside from, "just do it, its the thing
to do." and noone is going to buy that.

Sounds like a group out-of-control.

Sadly you either have the authority to enforce coding standards, or
you do not. If you do then "just do it, its the thing to do" OR *its
your job* is the only reliable answer. Otherwise, live with it chewing
away as opportunities present themselves, or seek other employment.

Number 8 above
"8) Every .cpp file should compile into a .obj file without error
or warning on its own"
can be corrected with daily builds and penalties for "breaking the
build".

-ralph
 
C

Christopher

It seems irrational to me to have classes in .h and templates in .hpp;
either use .h for all C++ code; .hpp for all C++ code.

It seems popular to use .hpp for C++ code and .h for C code these days.

/Leigh

That would be fine with me.
I am looking for some explanation I can give though for why not to put
a class definition in a .cpp file. What would you say?
 
A

Alf P. Steinbach

If you were on a team of developers that had little C++ experience,
how would you go about explaining the reasoning as to why the
following rules should be followed? (Or why they shouldn't)

1) Class defintions go in their own .h (or .hpp for templates) file
named after the class
1a) Every class should have its own .h (or .hpp for templates) file

Instead of such mechanical rules, have a rule about clarity and possibly
about testability.

Two or more classes may be strongly coupled and belong in the same header.

Many classes are just implementation details and do not deserve their
own headers.

1b) A .h file should never contain class implementation (except for
inline functions or methods)

The "except" makes this rule self-contradictory.

Perhaps the author intended to write a rule about always making sure
that a function definition in a header file is `inline`, whether
explicitly or implicitly by being defined in a class definition.


2) Class implementations go in their own .cpp file (except for
templates)

That might help to reduce build times for a complex system.

But note that "complex" is an euphemism for "spaghetti".

Better, IMO, to instead avoid the spaghetti.

2a) A .cpp should never contain a class definition

That's incredibly restricting.

For example, it would preclude the ordinary PIMPL idiom, or else force
an extra header file for that.

3) One should not define multiple classes in a single .h file
3a) Nested class defintions should be avoided without good reason
(what's good reason?)

These two rules contradict each other.

6) Variables should never be defined in a .h file

That's idiotic, it precludes defining constants.

7) Globals should not be defined in a .h file

It's a good idea to avoid global variables in general.

But this connection with .h files is meaningless.

8) Every .cpp file should compile into a .obj file without error or
warning on its own.

Good idea, and I do agree, although many people disagree.

Those who disagree find it more work to structure the code so as to get
rid of warnings, than to merely ignore the warnings, and they argue that
it is futile to try to shut up future compiler versions.

For example, building the Boost library produces a lot of warnings.

i.e In Visual Studio, you should be able to right click a .cpp in
the source tree and choose compile, without error or warning in the
output.

Yes, I think that's a good ideal.

Also, with any compiler, remember to enable a higher warning level than
default, but not so extreme as to be impractical.

For example, with Visual C++ use at least /W4, and with g++ use at least
-Wall

----

Sadly, I find myself having to justify these things. (of course
someone might point out I am wrong or exceptions to the above), but
these are things that I've always had drilled into my head throughout
the years and have rarely come acorss other developers that didn't do
the same.

Oh, you've been unfortunate.

I am finding it frustrating to work on a project where 30
classes defintions reside in the .h same .h file, a single .cpp file,
or worse a precompiled header.

Yes, that's bad, but I think not solvable by mechanical rules that are
just as bad (in the other direction).

There is discussion, but I have to
explain reasoning.

So far, I've come up with the testability argument:
When unit testing one frequently wants to test a single class. A proxy
class may need to be created to test its protected or privare methods.
Proxies may have to be created for its input and outputs. I should be
able to include a single .h file, link in the appropriate .obj files
and compile a unit test without the added clutter of satisfying
includes or linkage needed by unrelated classes.

I don't know what else to say aside from, "just do it, its the thing
to do." and noone is going to buy that.

Cheers & hth.,

- Alf
 
C

Christopher

Sounds like a group out-of-control.
Sadly you either have the authority to enforce coding standards, or
you do not. If you do then "just do it, its the thing to do" OR *its
your job* is the only reliable answer. Otherwise, live with it chewing
away as opportunities present themselves, or seek other employment.

I am beginning to think that might be the case, but if the boss says
"I beleive you, you just have to give some reasoning aside from I said
so." Then I wanted to at least try before joining the "I am looking
for employment" group again.
Number 8 above
"8) Every .cpp file should compile into a .obj file without error
 or warning on its own"
can be corrected with daily builds and penalties for "breaking the
build".

Not really, because the build in its entirety brings in other .cpp
and .h files as well as precompiled headers, in which things were
defined in the wrong places, but the compiler remains happy. It just
ends up being a fragile build that breaks often, because standards
weren't followed. When compiling just one .cpp by itself, everything
has to be defined and correct.
 
G

Goran

If you were on a team of developers that had little C++ experience,
how would you go about explaining the reasoning as to why the
following rules should be followed? (Or why they shouldn't)

1) Class defintions go in their own .h (or .hpp for templates) file
named after the class

Don't know about hpp for templates. It's *.h or *.hpp for everything
if you ask me. If there is only one class ion the file, or if it's
clearly the "main" class in it, then class_name.h is only natural.
1a) Every class should have its own .h (or .hpp for templates) file

Not so sure about that. All sorts of auxiliary artifacts can just as
well be tagged along their principal stuff.
1b) A .h file should never contain class implementation (except for
inline functions or methods)

Purely mechanically, this doesn't work due to C compilation model: if
the class parts are defined in a header, and said header is included
in more than one translation unit (source file), linker will encounter
duplicate symbols.
2) Class implementations go in their own .cpp file (except for
templates)

Same as above
2a) A .cpp should never contain a class definition

Disagreed. There's classes that will only be used in one translation
unit. What can one gain by making another trivial header?
3) One should not define multiple classes in a single .h file
3a) Nested class defintions should be avoided without good reason
(what's good reason?)

Good reason: nested class is used exclusively in context of the
nesting class, possibly as a helper.

Private nested classes should be avoided. They are better off in
implementation file, as not to create additional compile-time
dependency where there's no logical one.
6) Variables should never be defined in a .h file

Same as for classes - duplicate symbols galore. Exception: literal
constants. If these are not constants, there should ideally be 0 of
those in any given codebase.
7) Globals should not be defined in a .h file

I am not sure to understand the difference between a variable and a
global?
8) Every .cpp file should compile into a .obj file without error or
warning on its own.
     i.e In Visual Studio, you should be able to right click a .cppin
the source tree and choose compile, without error or warning in the
output.

Except for precompiler header, which one should be using to save
compilation time. IOW, if precompiled header is used and compiled,
then any translation unit should compile.

Otherwise, if you can't compile without errors, you can't compile, end
of, so that's a given. As for warnings... When compiler emits a
warning, it does it for a reason. Coder isn't smarter than compiler as
far as formal verification goes. If there's a warning, coder should
first try to change the code so that compiler has no reason for
nagging. That usually ends in a better design. Casting or other
compiler-gagging come distant second as idea.
Sadly, I find myself having to justify these things.

Sadly is a good word. What, do directory entries cost these people
money?
(of course
someone might point out I am wrong or exceptions to the above), but
these are things that I've always had drilled into my head throughout
the years and have rarely come acorss other developers that didn't do
the same. I am finding it frustrating to work on a project where 30
classes defintions reside in the .h same .h file, a single .cpp file,
or worse a precompiled header. There is discussion, but I have to
explain reasoning.

Ugh. That's a clear-cut sign that someone doesn't know how to work
with C compilation model.

Goran.
 
T

Tobias Müller

Christopher said:
That would be fine with me.
I am looking for some explanation I can give though for why not to put
a class definition in a .cpp file. What would you say?

Generally, you don't #include .cpp files (this is what .h files are made
for), so a class defined in a cpp file is really only visible in that
single file.

Normally you want a class to be reusable in other files, but there are rare
cases where it makes sense to have a class that is "private" to some .cpp
file and you don't want it to be used by others.

Tobi
 
A

Alf P. Steinbach

Traditionally constants are called constants not variables.

You got a point.

I was associating too strongly to formal terminology.


Cheers, & thanks,

- Alf
 
R

Rui Maciel

Christopher said:
If you were on a team of developers that had little C++ experience,
how would you go about explaining the reasoning as to why the
following rules should be followed? (Or why they shouldn't)

1) Class defintions go in their own .h (or .hpp for templates) file
named after the class
1a) Every class should have its own .h (or .hpp for templates) file
1b) A .h file should never contain class implementation (except for
inline functions or methods)

2) Class implementations go in their own .cpp file (except for
templates)
2a) A .cpp should never contain a class definition

3) One should not define multiple classes in a single .h file
3a) Nested class defintions should be avoided without good reason
(what's good reason?)

6) Variables should never be defined in a .h file
7) Globals should not be defined in a .h file
8) Every .cpp file should compile into a .obj file without error or
warning on its own.
i.e In Visual Studio, you should be able to right click a .cpp in
the source tree and choose compile, without error or warning in the
output.
----

Sadly, I find myself having to justify these things. (of course
someone might point out I am wrong or exceptions to the above), but
these are things that I've always had drilled into my head throughout
the years and have rarely come acorss other developers that didn't do
the same. I am finding it frustrating to work on a project where 30
classes defintions reside in the .h same .h file, a single .cpp file,
or worse a precompiled header. There is discussion, but I have to
explain reasoning.

Separating declarations from implementations and mandating that each class
should be defined and implemented in separate source files are a couple of
practices which help track what changes were made to each individual
component and who made those changes. With this, auditing the code becomes
a bit simpler.

This practice also reduces the amount of potential merging conflicts any
commit might induce.


Rui Maciel
 
R

ralph

I am beginning to think that might be the case, but if the boss says
"I beleive you, you just have to give some reasoning aside from I said
so." Then I wanted to at least try before joining the "I am looking
for employment" group again.


Not really, because the build in its entirety brings in other .cpp
and .h files as well as precompiled headers, in which things were
defined in the wrong places, but the compiler remains happy. It just
ends up being a fragile build that breaks often, because standards
weren't followed. When compiling just one .cpp by itself, everything
has to be defined and correct.

I was thinking of intermediate or validation "builds" as part of the
daily build. Which is something I often enforce with large projects,
ie, no translation unit gets through with warnings and errors. Even
so, as you noted, the build is fragile and will destruct sooner or
later. Making those responsible for breaking the build - responsible
for repairing the build, will go a long way to getting the message
across.

Also frequent Code Reviews will help.

Setting up and maintaining an enterprise level development effort is
not a trivial exercise. It encompasses more that just "coding
standards".

As others noted not all your rules are "unquestionable". Few *best
practices* are. There are always exceptions, though as the proverb
says "it is the exception that makes the rule".

You have to start somewhere. Having a good reason to break a rule is
very useful in gaining an understanding of why the rule was there in
the first place.

Hold on. Chew away. Be happy if you can make a change. Don't beat
yourself up when you can't. (ie, don't take it home with you. <g>)

-ralph
 
C

Christopher

Not so sure about that. All sorts of auxiliary artifacts can just as
well be tagged along their principal stuff.

I suppose a functor used for comparison might be an example. I need to
explain somehow what kinds of things would be an auxilary artifact
that is acceptable and what obviously requires seperation. I suppose
it is just intuitive to most of us.

I think what was said about nested classes is a good start. If the
class is only used by the main class in the file.

Purely mechanically, this doesn't work due to C compilation model: if
the class parts are defined in a header, and said header is included
in more than one translation unit (source file), linker will encounter
duplicate symbols.

Same as above

I cannot visualize this scenario. Can you give a code example in which
any part of class implementation is required to be in the header,
excluding the use of templates?

Use of inclusion guards has always taken care of duplicate symbols
when a header is included in more than one source file and is pretty
standard practice in my experience.


Disagreed. There's classes that will only be used in one translation
unit. What can one gain by making another trivial header?

In this case, what's wrong with putting it in the header? I suppose
until I can visualize your argument for 1b and 2, I have trouble
seeing this as well.

When I see an unfamilair type in a source file, I would immeditaley
look in the corresponding .h file for its defintion. I'd hate to rely
on "not-so-intelli-sense" or something similar.

If inclusion guards are used, I don't see the down side.

Good reason: nested class is used exclusively in context of the
nesting class, possibly as a helper.

Good reason!

Private nested classes should be avoided. They are better off in
implementation file, as not to create additional compile-time
dependency where there's no logical one.

I could see this making sense pending more explanation to the previous
arguments.

Same as for classes - duplicate symbols galore. Exception: literal
constants. If these are not constants, there should ideally be 0 of
those in any given codebase.

Whoops, I believe I meant to say variable _declaration_. Definition
and Declaration seem to very confusing terms as they have different
meanings for classes and variables in C++.

What I mean is
int x = 10; should not appear in a .h file.
int x; However, may appear in a .h file, but I'd still argue that
there is probably a better way then using a global.

const int x = 10; Should not appear in a .h file
const int x; May appear in a .h file, but I'd rather see:

static int GetX() const
{
return 10;
}

because some other global MyClass might make use of x and then I run
into the static intialization fiasco.


or better if only used in one class:

class WhereXIsUsed
{
public:
private:
const int m_x;
};

or possibly something like

struct SystemConfigurationDefaults
{
const int m_x;
};

I am not sure to understand the difference between a variable and a
global?

One is a superset of the other.
But again, I think I meant declared instead.


Except for precompiler header, which one should be using to save
compilation time. IOW, if precompiled header is used and compiled,
then any translation unit should compile.

When it comes to precompiled headers, what I am trying to convey is
that everything should compile without them.
Precomiled headers should be used as a build optimization only, if at
all, and not as part of the implementation.

How I've been doing it:

---
/*
* foo.h
*/
#ifndef FOO_H
#define FOO_H

#include <iostream>

// Use of iostream
// SNIP
#endif

---
/*
* foo.cpp
*/
#include "precompiled-header.h"
#include "foo.h"

#include <algorithm>

// Use of algorithm
//SNIP

---
/*
* precompiled-header.h
*/
#include <algorithm>
#include <iostream>
// SNIP

Allows for foo.obj regardless of whether or not the precompiled header
was compiled. If the pre-compiled header was used, it speeds up build
time in some scenarios.


What I've come across that I believe is incorrect, but still compiles
if build order happens to work out:
---
/*
* foo.h
*/
#ifndef FOO_H
#define FOO_H

// Use of iostream
// SNIP
#endif

---
/*
* foo.cpp
*/
#include "precompiled-header.h"

// Use of algorithm
//SNIP

---
/*
* precompiled-header.h
*/
#include "foo.h"

#include <algorithm>
#include <iostream>
// SNIP

My difficulty, assuming I am correct (because I am totally willing to
accept correction with explanation), is expressing this in words.

Sadly is a good word. What, do directory entries cost these people
money?

I've heard words like "complexity" and "clutter"
Ironic, because I use words like "simple" and "logical"
 
I

Ian Collins

I disagree with your rule 6. It precludes #define.

Which was "Variables should never be defined in a .h file". Context is
good.


Why would you be using #define for variables in C++?
 
J

Jorgen Grahn

....


The "except" makes this rule self-contradictory.

Perhaps the author intended to write a rule about always making sure
that a function definition in a header file is `inline`, whether
explicitly or implicitly by being defined in a class definition.

That still does not cover templates though. You may want to define
template classes, but not ask for inlining of everything.

....
Yes, I think that's a good ideal.

Also, with any compiler, remember to enable a higher warning level than
default, but not so extreme as to be impractical.

For example, with Visual C++ use at least /W4, and with g++ use at least
-Wall

I've mentioned it before, but IMHO -Wall is far from enough. I default
to

-Wall -Wextra -pedantic -std=c++98 -g -O3

/Jorgen
 
T

Tobias Müller

Christopher said:
Use of inclusion guards has always taken care of duplicate symbols
when a header is included in more than one source file and is pretty
standard practice in my experience.

Inclusion guards don't help you here, at least if you have more than one
translation unit.

Inclusion guards make sure that you don't have duplicate class definitions
in one TU. However, every header file needs to be visible in every TU or
else you can't use the classes defined in that header. And if you have
method implementations in the header, the code will be generated in every
TU and evetually the linker will complain (not the compiler).

Tobi
 
J

Juha Nieminen

Christopher said:
1) Class defintions go in their own .h (or .hpp for templates) file
named after the class

I never use ".h" as a file name extension for C++ headers for a rather
obvious reason: It's not C code and I want to distinguish C code from C++
code unambiguously. Also, I don't see why headers containing templated
code should be named differently from headers that don't.

From unix I am accustomed to using .cc and .hh extensions, but that's
another story.
1a) Every class should have its own .h (or .hpp for templates) file

You are polluting the global namespace this way for classes that could
well be compilation-unit-local. Such classes should go into a nameless
namespace, which is incompatible with a public header file. (Ok,
technically speaking you can put a nameless namespace in a header file
because, after all, it's just C++ code like everything else, but the
advantage of doing this is dubious. You will only be including it in
the compilation unit where it's used, and including it anywhere else
would be useless, as it would only define an unimplemented local class.)

You might have learned otherwise, but I have learned that public interfaces
should be as minimal as possible, and polluting the global namespace with
local types is not good design.
1b) A .h file should never contain class implementation (except for
inline functions or methods)

That's a null statement. If a header file contains implementations,
they will be inline by necessity (else you'll get linker errors if the
header is included more than once), so that rule isn't really saying
anything.

Perhaps if you had said: "A header file should contain inline function
implementations only if there's a very good reason for them. Otherwise
they should go to the correspondent compilation unit."
2) Class implementations go in their own .cpp file (except for
templates)

Technically speaking templates can be declared in a header file and
implemented in a compilation unit even in cases where the template is
used somewhere else besides that compilation unit (yes, even without
support for export; it can be done with explicit template instantiation),
but that's not a usual circumstance. But I digress.
2a) A .cpp should never contain a class definition

Why not? If a class is used only in that one compilation unit, and
especially if it's small, what's the problem?

Think about this: What would be the difference between a private inner
class and a class local to the compilation unit (ie. in a nameless namespace),
except for scope? Would the former be ok but not the latter? Why?
(The testability argument doesn't hold because you cannot test a private
inner class from the outside.)

(And please don't tell me you oppose private inner classes too.)
3) One should not define multiple classes in a single .h file

If two classes are relatively small and strongly related to one other,
why not? A typical example would be a template class and a specialization
for a specific template type. If you put them in separate header files, you
would have a small problem in what to include. There are many non-templated
examples as well.
3a) Nested class defintions should be avoided without good reason
(what's good reason?)

I don't see why inner classes "should be avoided".

In general class design should be as simple as possible. That includes,
among many other things, minimizing the amount of inner classes. However,
there's nothing special about them in particular that should be avoided.

Iterators are good examples of public inner classes. Why should they be
avoided? And if some private implementation of the class needs a private
class, then why not? (In fact, sometimes trying to religiously avoid inner
classes can make your code much more complicated and harder to manage.)
6) Variables should never be defined in a .h file

There are some situations where extern variables are justified. Although
even in those cases they should usually be declared inside a namespace to
minimize global namespace pollution. (std::cout would be an example.)
7) Globals should not be defined in a .h file

Well, duh. You'll get a linker error if you do. (At least if you include
the header in more than one place.)
8) Every .cpp file should compile into a .obj file without error or
warning on its own.

Hmm, is there any other way? Or what do you mean "on its own"? I don't
even know of any other way of compiling a C++ program than one compilation
unit at a time.
 
G

Goran

I suppose a functor used for comparison might be an example. I need to
explain somehow what kinds of things would be an auxilary artifact
that is acceptable and what obviously requires seperation. I suppose
it is just intuitive to most of us.

I think what was said about nested classes is a good start. If the
class is only used by the main class in the file.




I cannot visualize this scenario. Can you give a code example in which
any part of class implementation is required to be in the header,
excluding the use of templates?

I poorly expressed myself? When I said "same as above", I meant "you
have to put class implementation in it's own implementation because
otherwise linker encounters duplicate symbols". So class
implementations absolutely must go in an implementation file. Perhaps
it's own implementation file (e.g. small related thingy can tag
along).
Use of inclusion guards has always taken care of duplicate symbols
when a header is included in more than one source file and is pretty
standard practice in my experience.



In this case, what's wrong with putting it in the header? I suppose
until I can visualize your argument for 1b and 2, I have trouble
seeing this as well.

If code artifact is used in only one translation unit, it does not
require a header, that's all. Make it if you wish, but it's only more
files to go around.
When I see an unfamilair type in a source file, I would immeditaley
look in the corresponding .h file for its defintion. I'd hate to rely
on "not-so-intelli-sense" or something similar.

What's wrong with grep or "Find in files" in VS?
If inclusion guards are used, I don't see the down side.



Good reason!


I could see this making sense pending more explanation to the previous
arguments.



Whoops, I believe I meant to say variable _declaration_. Definition
and Declaration seem to very confusing terms as they have different
meanings for classes and variables in C++.

What I mean is
int x = 10; should not appear in a .h file.

That doesn't work anyhow. For example (it's the example you're asking
for elsewhere, too), you can compile (BUT NOT LINK)

h.h
#ifndef whatever
#define whatever
int x=10;
#endif

s.cpp
#include "h.h"
void f()
{
x++;
}

main.cpp
#include "h.h"
int main(int, const char*[])
{
x++
}
int x; However, may appear in a .h file, but I'd still argue that
there is probably a better way then using a global.

I like

extern int x;

(explains the intent better IMO)
const int x = 10; Should not appear in a .h file
const int x; May appear in a .h file, but I'd rather see:

static int GetX() const
{
   return 10;

}

because some other global MyClass might make use of x and then I run
into the static intialization fiasco.

or better if only used in one class:

class WhereXIsUsed
{
public:
private:
  const int m_x;

};

If only used in one class, it's best declared in class's
implementation. That's (for me) to avoid compile-time dependency: you
can change it in *.cpp all you like, you don't recompile all other
*.cpp-s that include your_class.h
or possibly something like

struct SystemConfigurationDefaults
{
   const int m_x;

};


One is a superset of the other.
But again, I think I meant declared instead.



When it comes to precompiled headers, what I am trying to convey is
that everything should compile without them.
Precomiled headers should be used as a build optimization only, if at
all, and not as part of the implementation.

Yes, agreed.
How I've been doing it:

---
/*
* foo.h
*/
#ifndef FOO_H
#define FOO_H

#include <iostream>

// Use of iostream
// SNIP
#endif

---
/*
* foo.cpp
*/
#include "precompiled-header.h"
#include "foo.h"

#include <algorithm>

// Use of algorithm
//SNIP

---
/*
* precompiled-header.h
*/
#include <algorithm>
#include <iostream>
// SNIP

Allows for foo.obj regardless of whether or not the precompiled header
was compiled. If the pre-compiled header was used, it speeds up build
time in some scenarios.

Actually, I like that. I was wrong when I said that you can build
"provided that precompiled header was built before" (and you are
right).

Goran.
 
A

Alf P. Steinbach

Purely mechanically, this doesn't work due to C compilation model: if
the class parts are defined in a header, and said header is included
in more than one translation unit (source file), linker will encounter
duplicate symbols.

I think the above is perhaps too vaguely expressed.

First, a "class definition" does not necessarily include definitions of
member functions.

Secondly, it's quite common to put also definitions of member functions
in a header. They need then to be either templates or `inline`. For
example, many Boost sub-libraries are header only.


Cheers & hth.,

- Alf
 
G

gwowen

Which was "Variables should never be defined in a .h file".  Context is
good.

Why would you be using #define for variables in C++?

In a header, you may want some C/C++ cross compatibility and the C
definition of what counts as a compile-time constant can make it the
least-unpleasant way to define a constant.

romanes.h:
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top