Is it necessary to declare the private section of a C++ class?

R

Ramon F Herrera

My program's files are structured like this:

- a small 'main.cpp' file, all it does is to call a class

- a rather large 'myclass.cpp' file, it contains the instantiation
public member and a lot of private stuff.

- a 'myclass.h' file which I have been unable to write properly. It
should have the declarations of its *.cpp counterpart.

Compile works fine, but the only way I have been able to link is by
having this line:

#include "myclass.cpp" <== I would like to have "myclass.h" here!

in the "main.cpp" file.

Needless to say the above is wasteful, since the "myclass.cpp" file is
probably compiled -or at least scanned- twice.

In this BOOK that I am READING, the author declares the whole
enchilada, and I don't understand why. I would only declare the public
part.

http://tinyurl.com/mwpq3b (Page 293, "Declarations and Definitions")

TIA,

-Ramon
 
R

Ramon F Herrera

Before I get into replying to this, I should say that I'm reading it
in comp.programming, and I hope you'll get much better results from
your (very sensible, in this case) comp.lang.c++ crosspost. Still,
let's see what we can do.

In

Ramon F Herrera wrote:






And in any case it's not scalable. Once you need that header stuff in
/two/ files, you're stuffed if you #include the C++ file.



That link shows me lots of screen furniture but no actual text from
the book. Perhaps it's a permissions thing. Anyway, no matter.

If you are okay with revealing the *structure* of a class to any old
programmer, and just hiding the *implementation*, then this is very
easy (see below). If you want to hide even the structure, then it's a
bit harder.

/* myclass.hpp */
#ifndef H_MYCLASS
#define H_MYCLASS 1
class myclass
{
  int x;
  void setx(int);
public:
  myclass(int);
  void inc();
  void dec();
  int get();};

#endif

/* myclass.cpp */
#include "myclass.hpp"
myclass::myclass(int x_)
{
  setx(x_); /* or use one of those fancy constructor init lists */}

void myclass::setx(int x_)
{
  x = x_;}

void myclass::inc()
{
  ++x;}

void myclass::dec()
{
  --x;

}

int myclass::get()
{
  return x;

}

/* main.cpp */
#include <iostream>
#include "myclass.hpp"

int main()
{
  myclass m(42);
  std::cout << "m = " << m.get() << std::endl;
  m.inc();
  std::cout << "m = " << m.get() << std::endl;
  m.dec();
  std::cout << "m = " << m.get() << std::endl;
  return 0;

}

This gives the output

m = 42
m = 43
m = 42

Like I said, that's the easy way. The hard way allows you to hide the
private interface details as well. I'm most definitely *not* going to
try to show you how to do this, because I'm way too likely to get it
wrong in the short time available to me to answer this question. But
at least I can tell you what to look up in your book: proxy classes.

NB If only you were using C, this would be dead easy. Opaque types are
a snap. But no, I'm not trying to persuade you to switch to C. You
now have two (non-exclusive) choices: wait for a rockin' reply from
comp.lang.c++, or look up proxy classes in your book.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within

Thanks, Richard:

Here is the full link to the book:

http://books.google.com/books?id=7c...esult&ct=result&resnum=7#v=onepage&q=&f=false

-Ramon
 
S

Saeed Amrollahi

My program's files are structured like this:

 - a small 'main.cpp' file, all it does is to call a class

 - a rather large 'myclass.cpp' file, it contains the instantiation
public member and a lot of private stuff.

 - a 'myclass.h' file which I have been unable to write properly. It
should have the declarations of its *.cpp counterpart.

Compile works fine, but the only way I have been able to link is by
having this line:

#include "myclass.cpp"  <== I would like to have "myclass.h" here!

in the "main.cpp" file.

Needless to say the above is wasteful, since the "myclass.cpp" file is
probably compiled -or at least scanned- twice.

In this BOOK that I am READING, the author declares the whole
enchilada, and I don't understand why. I would only declare the public
part.

http://tinyurl.com/mwpq3b(Page 293, "Declarations and Definitions")

TIA,

-Ramon

Hi Ramon

In a typical C++ program with clean physical structure, you have n .h
files for class declaration/definition and n corresponding .cpp files
for
member functions defintions and 1 .cpp file as a driver. the main
function
is in the last .cpp file.
For separate compilation achievement, you have to include each .h file
in
each corresponding .cpp file and all .h files in the driver .cpp file
Chapter 9 of The C++ Programming Language (special edition) by
Bjarne Stroustrup is very helpful.

Regards,
-- Saeed Amrollahi
 
R

Ramon F Herrera

Hi Ramon

In a typical C++ program with clean physical structure, you have n .h
files for class declaration/definition and n corresponding .cpp files
for
member functions defintions and 1 .cpp file as a driver. the main
function
is in the last .cpp file.
For separate compilation achievement, you have to include each .h file
in
each corresponding .cpp file and all .h files in the driver .cpp file
Chapter 9 of The C++ Programming Language (special edition) by
Bjarne Stroustrup is very helpful.

Regards,
  -- Saeed Amrollahi


Thanks for your kind reply, Saeed.

It looks like your posting points in the precise direction. My C
programming background is an obstacle. I am not used to having
executable statements in header files.

Online material is most welcome, guys.

Thx,

-Ramon
 
I

Ian Collins

Richard said:
Before I get into replying to this, I should say that I'm reading it
in comp.programming, and I hope you'll get much better results from
your (very sensible, in this case) comp.lang.c++ crosspost. Still,
let's see what we can do.

Which is why he should have asked here!
Like I said, that's the easy way. The hard way allows you to hide the
private interface details as well. I'm most definitely *not* going to
try to show you how to do this, because I'm way too likely to get it
wrong in the short time available to me to answer this question. But
at least I can tell you what to look up in your book: proxy classes.

No, not proxy classes, proxies have a different use. What he should
look up is the PIMPL idiom.
NB If only you were using C, this would be dead easy. Opaque types are
a snap. But no, I'm not trying to persuade you to switch to C. You
now have two (non-exclusive) choices: wait for a rockin' reply from
comp.lang.c++, or look up proxy classes in your book.

If you can do it in C with opaque types, you can do it in C++ with type
safety!
 
I

Ian Collins

Ramon F Herrera wrote:

[This really only belongs in c.l.c++]
My program's files are structured like this:

- a small 'main.cpp' file, all it does is to call a class

- a rather large 'myclass.cpp' file, it contains the instantiation
public member and a lot of private stuff.

- a 'myclass.h' file which I have been unable to write properly. It
should have the declarations of its *.cpp counterpart.

Compile works fine, but the only way I have been able to link is by
having this line:

#include "myclass.cpp" <== I would like to have "myclass.h" here!

in the "main.cpp" file.

You aren't using your tools correctly, you should compile the two .cpp
files separately and link the resulting objects files to make your
executable. Which compiler/platform are you using?
Needless to say the above is wasteful, since the "myclass.cpp" file is
probably compiled -or at least scanned- twice.

In this BOOK that I am READING, the author declares the whole
enchilada, and I don't understand why. I would only declare the public
part.

Then how and where do you intend declaring the private part of your class?
 
R

Ramon F Herrera

Ramon F Herrera wrote:

[This really only belongs in c.l.c++]


My program's files are structured like this:
 - a small 'main.cpp' file, all it does is to call a class
 - a rather large 'myclass.cpp' file, it contains the instantiation
public member and a lot of private stuff.
 - a 'myclass.h' file which I have been unable to write properly. It
should have the declarations of its *.cpp counterpart.
Compile works fine, but the only way I have been able to link is by
having this line:
#include "myclass.cpp"  <== I would like to have "myclass.h" here!
in the "main.cpp" file.

You aren't using your tools correctly, you should compile the two .cpp
files separately and link the resulting objects files to make your
executable.
> Which compiler/platform are you using?

Linux/g++, of course.
> Then how and where do you intend declaring the private part of your
class?

I am pretty sure my problem is the lack of familiarity with the C++
file division structure. I am reading the topic, as we speak.

-Ramon
 
J

James Kanze

My program's files are structured like this:
- a small 'main.cpp' file, all it does is to call a class
- a rather large 'myclass.cpp' file, it contains the
instantiation public member and a lot of private stuff.
- a 'myclass.h' file which I have been unable to write
properly. It should have the declarations of its *.cpp
counterpart.
Compile works fine, but the only way I have been able to link
is by having this line:
#include "myclass.cpp" <== I would like to have "myclass.h" here!
in the "main.cpp" file.
Needless to say the above is wasteful, since the "myclass.cpp"
file is probably compiled -or at least scanned- twice.

It's also incorrect, as you'll end up with multiple definitions
(unless all of the functions are inline).
In this BOOK that I am READING, the author declares the whole
enchilada, and I don't understand why.

The text you point to in the book doesn't specify how the
definitions are ventilated into files.
I would only declare the public part.

A class definition is closed. It can't be extended. Once
you've written:
class Toto
{
// ...
} ;
you can't have any other definition of Toto, and you cannot add
members elsewhere. This definition must be visible (and the
same) in all modules which use the class, so it belongs in the
header.

You can (and should) define the member functions elsewhere;
unless the member functions are inline, you should define them
in a source file. If the class is part of a library, you should
probably each function in a separate source file, otherwise,
it's usually more convenient to have a single source file for
all of the functions in a class.

Depending on the context and the complexity of the class, you
may find that this results in too much being exposed in the
header. If this is an issue (and it will be with many classes
in a large application), then you can use the compilation
firewall idiom (sometimes known as the pimpl idiom, or the
Cheshire cat idiom).
 
R

Rune Allnor

In this BOOK that I am READING, the author declares the whole
enchilada, and I don't understand why.

From the point of view of an author who writes about the
C++ language in general (as opposed on any particular
system / implementation), this structure makes a lot of
sense since his focus is on how to structure the classes etc,
not the source code. The exact voodoo needed (or preferred)
to structure the source code properly varies a bit from
system to system.

MS Visual Studio needs - surprise... - some proprietary
stuff in addition to the standard way of doing things, so
one would need think very carefully through how one organizes
the source code if one wants to write portable code.

However, those types of details don't belong in a text on
the general C++ language, so authors tend to ignore those
sorts of things.

Apart from that, C++ template programming is implemented
only in .h files: The idea is that implementers define
most (but not all) of the source code, and the user
supplies the last missing details when he call the libraries.
In other words, the compiler does not have all necessary
information needed to produce linkable code until the user
actually calls the function or instantiates the class
in some application.

This, in turn, means that the implementer has to specify
a lot of functionality, by means of executable code, in
the .h files, since there is no way the compiler can get
anything useful from an incomplete .cpp file.

And of course, there are limitations: Executable code
that relies on pre-compiled linkable components should
*not* be called in .h files.
I would only declare the public part.

With with pre-compiled linkable libraries, you can do
exactly like you want: The user has no business knowing
what goes on inside the component, so in that case
it is prefectly possible to supply a .h file that only
declares the public interface.

But again, with template code, the compiler does not
have enough information to produce a useful result until
the user actually calle sthe component. At that time,
it needs to know everything. So in that case you
not only have to expose the protected and private
declarations (to the compiler, not the user) - you even
have to expose the source code.

Rune
 
R

red floyd

Ramon said:
My program's files are structured like this:

- a small 'main.cpp' file, all it does is to call a class

- a rather large 'myclass.cpp' file, it contains the instantiation
public member and a lot of private stuff.

- a 'myclass.h' file which I have been unable to write properly. It
should have the declarations of its *.cpp counterpart.

Compile works fine, but the only way I have been able to link is by
having this line:

Since we can't see your code, we can only guess.

Is your myclass class a template? If so, please see FAQ's 35.12
and 35.13.

http://parashift.com/c++-faq-lite/templates.html#faq-35.12
 
J

James Kanze

From the point of view of an author who writes about the C++
language in general (as opposed on any particular system /
implementation), this structure makes a lot of sense since his
focus is on how to structure the classes etc, not the source
code. The exact voodoo needed (or preferred) to structure the
source code properly varies a bit from system to system.

Not really. How to invoke the compiler varies immensely from
system to system, but even how to tell it how to find the
necessary parts is in practice very similar from one compiler to
the next. (Almost always a -I or /I for specifying include
paths, for example.)
MS Visual Studio needs - surprise... - some proprietary
stuff in addition to the standard way of doing things,

Bullshit. I recently ported a very large chunk of C++ developed
under Unix to Windows VC++, and changed absolutely nothing in my
file organization. If you're doing system dependent code,
you'll need to include different system headers, of
course---<unistd.h> will get you about as far under Windows as
Apart from that, C++ template programming is implemented only
in .h files:

It depends. My template implementations are in .tcc files. At
any rate, the code in question wasn't template code. And of
course, if the implementation is standard compliant (e.g. like
Comeau), then you can put the template implementation directly
in the source files where it belongs.

[...]
And of course, there are limitations: Executable code
that relies on pre-compiled linkable components should
*not* be called in .h files.

It's not clear what you mean here. Code which depends on
another library follows the same rules as any other code.

[...]
With with pre-compiled linkable libraries, you can do exactly
like you want: The user has no business knowing what goes on
inside the component, so in that case it is prefectly possible
to supply a .h file that only declares the public interface.

The class definitions must be complete (in the header file) if
the client code is to instantiate instances of the class.
Including any private members.
 
R

Rune Allnor

Bullshit.

If you want to play with console applications and use the
templated containers in the STL, you need to set the project
up to use precompiled headers. Once you do that, you are
forced to include a MSVS-specific header "stdafx.h" in the
..cpp files, or the compiler chokes. You can circumvent that
by setting up a .cxx file that includes stdafx.h and the
..cpp file that contains the standard code.

Rune
 
N

Nick Keighley

If you want to play with console applications and use the
templated containers in the STL, you need to set the project
up to use precompiled headers. Once you do that, you are
forced to include a MSVS-specific header "stdafx.h" in the
.cpp files, or the compiler chokes. You can circumvent that
by setting up a .cxx file that includes stdafx.h and the
.cpp file that contains the standard code.

No.

I write console programs for windows and GUI programs for windows.
I don't use pre-compiled headers and I never include stdafx.h
 
J

Jerry Coffin

[ ... ]
If you want to play with console applications and use the
templated containers in the STL, you need to set the project
up to use precompiled headers. Once you do that, you are
forced to include a MSVS-specific header "stdafx.h" in the
.cpp files, or the compiler chokes. You can circumvent that
by setting up a .cxx file that includes stdafx.h and the
.cpp file that contains the standard code.

Where in the world did you get these ideas? None of them is even
close to correct.

VS/VC++ does not require that you use pre-compiled headers _ever_!
Using them, at all, is purely your own choice -- they do (or at least
can) make compilation faster, but that's all they were ever even
intended to do.

In any case, the standard library headers wouldn't be the reason to
use pre-compiled headers anyway. The real reason comes down to ONE
header: <windows.h>. Along with the others it includes, <windows.h>
is why pre-compiled headers were invented in the first place, and
still the primary reason to consider using them. If you aren't
(possibly indirectly) including that, chances are that you have no
reason to even consider using pre-compiled headers at all.
 
R

Rune Allnor

[ ... ]
If you want to play with console applications and use the
templated containers in the STL, you need to set the project
up to use precompiled headers. Once you do that, you are
forced to include a MSVS-specific header "stdafx.h" in the
.cpp files, or the compiler chokes. You can circumvent that
by setting up a .cxx file that includes stdafx.h and the
.cpp file that contains the standard code.

Where in the world did you get these ideas? None of them is even
close to correct.

That was the only way I got MSVC to work when I first
started using it. I was a bit PO'd by it at the time,
but decided to leave it at that. From the responses in
this thread it seems it might be worth reviewing those
details again.

Rune
 
A

Alf P. Steinbach

* Jerry Coffin:
[ ... ]
If you want to play with console applications and use the
templated containers in the STL, you need to set the project
up to use precompiled headers. Once you do that, you are
forced to include a MSVS-specific header "stdafx.h" in the
.cpp files, or the compiler chokes. You can circumvent that
by setting up a .cxx file that includes stdafx.h and the
.cpp file that contains the standard code.

Where in the world did you get these ideas? None of them is even
close to correct.

VS/VC++ does not require that you use pre-compiled headers _ever_!
Using them, at all, is purely your own choice -- they do (or at least
can) make compilation faster, but that's all they were ever even
intended to do.

In any case, the standard library headers wouldn't be the reason to
use pre-compiled headers anyway. The real reason comes down to ONE
header: <windows.h>. Along with the others it includes, <windows.h>
is why pre-compiled headers were invented in the first place, and
still the primary reason to consider using them. If you aren't
(possibly indirectly) including that, chances are that you have no
reason to even consider using pre-compiled headers at all.

Well, that rationale may or may not be correct. With the Microsoft toolchain
<windows.h> is about 10 times larger than <iostream> (after preprocessing). With
the GNU toolchain they are about the same size.

Yeah, I know, I've described [windows.h] as "the mother of all header files" myself.

But the evidence doesn't bear that out.


Cheers,

- Alf


PS: Now I'm starting to HATE Mozilla. Firefox is the slowest beast on Mother
Earth, and Thunderbird informs me that "you can't send to more than one news
server at a time". For f*ck's sake, I'm *crossposting* to 2 newsgroups since the
thread is cross-posted, posting to the *same* single server. So, posted only to
[clc++]. Sorry bout the language but I'm upset: f****g braindead Mozilla.
 
J

Jerry Coffin

* Jerry Coffin:

[ ... ]
In any case, the standard library headers wouldn't be the reason
to se pre-compiled headers anyway. The real reason comes down to
ONE header: <windows.h>. Along with the others it includes,
<windows.h> is why pre-compiled headers were invented in the
first place, and still the primary reason to consider using them.
If you aren't (possibly indirectly) including that, chances are
that you have no reason to even consider using pre-compiled
headers at all.

Well, that rationale may or may not be correct. With the Microsoft toolchain
<windows.h> is about 10 times larger than <iostream> (after preprocessing). With
the GNU toolchain they are about the same size.

Yeah, I know, I've described [windows.h] as "the mother of all
header files" myself.

But the evidence doesn't bear that out.

It's not clear exactly what "that" means in this case.

The evidence seems to indicate that with VC++, <windows.h> is still
probably the main reason to use pre-compiled headers.

Unless gcc supports pre-compiled headers, however, any relationship
between its header sizes and the benefits of pre-compiled headers
sounds to me like it's pretty tenuous and hypothetical -- i.e. what
might happen if 1) gcc did support pre-compiled headers, or 2) what
might happen if MS used headers more like gcc's.

If there's a relationship between the sizes of gcc's headers, and the
benefits of using pre-compiled headers with VC++, perhaps you can
explain what it is in a bit more detail -- I'm having a hard time
seeing it.
 
J

James Kanze

If you want to play with console applications and use the
templated containers in the STL, you need to set the project
up to use precompiled headers.

Bullshit. The test programs for my Unix code all run as console
applications, and I have no idea how to use precompiled headers
with VC++ (or with any other compiler, for that matter).
Once you do that, you are forced to include a MSVS-specific
header "stdafx.h" in the .cpp files, or the compiler chokes.

My code compiles and runs without including stdafx.h. Most of
it compiles perfectly without including any Windows specific
header; it's only when I need to do system specific things (like
create a directory) that I need to include said:
You can circumvent that by setting up a .cxx file that
includes stdafx.h and the .cpp file that contains the standard
code.

Or by just not worrying about it.

I repeat---I recently ported a large block of code developed
under Unix to Windows and VC++. I had some problems with the
makefiles, because they use the Unix toolkit in many places, and
the Unix toolkits available for Windows are all a bit flaky.
And of course, I needed to reimplement the system dependent
stuff (but that was all isolated in a few components anyway).
But except for the system dependent stuff like creating
directories, my code required absolutely no changes.
 
J

Juha Nieminen

Richard said:
NB If only you were using C, this would be dead easy. Opaque types are
a snap.

It's refreshing to read some humoristic text in this group from time
to time. Thanks for the laugh.
 
J

Juha Nieminen

Ian said:
The same basic rules apply to C++ and C, declare in headers, define in
compilation units.

Moreover: Declare *the public interface* of your module in the header,
put everything else in the compilation unit.

Nothing stops you from declaring things inside the compilation unit
(if it's something used only there), and in fact that should usually be
maximized whenever possible and feasible. The header itself should be
minimized likewise.
 

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,770
Messages
2,569,584
Members
45,076
Latest member
OrderKetoBeez

Latest Threads

Top