[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

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

Ramon F Herrera

9/14/2009 7:05:00 AM


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.... (Page 293, "Declarations and Definitions")

TIA,

-Ramon

24 Answers

Richard Heathfield

9/14/2009 7:33:00 AM

0

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
<c9f9b93d-b683-4457-b0a7-3154af8ab7ae@g31g2000yqc.googlegroups.com>,
Ramon F Herrera wrote:

<snip>

> 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.

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.

> 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.... (Page 293, "Declarations and Definitions")

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....
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within

Ramon F Herrera

9/14/2009 7:38:00 AM

0

On Sep 14, 3:32 am, Richard Heathfield <r...@see.sig.invalid> wrote:
> 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
> <c9f9b93d-b683-4457-b0a7-3154af8ab...@g31g2000yqc.googlegroups.com>,
>
> Ramon F Herrera wrote:
>
> <snip>
>
> > 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.
>
> 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.
>
> > 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....(Page 293, "Declarations and Definitions")
>
> 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....
> 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=7cvPoe-Lr7cC&pg=PA293&lpg=PA293&dq=C%2B%2B+declare+vs.+define+class&source=bl&ots=u6zeBlTAFz&sig=rt79QEv5wiLCm48CLGn0oN_4Q60&hl=en&ei=h9CtSqO3Coe4NpTHmfIN&sa=X&oi=book_result&ct=result&resnum=7#v=onepage&q=&a...

-Ramon

amrollahi.saeed

9/14/2009 8:09:00 AM

0

On Sep 14, 10:04 am, Ramon F Herrera <ra...@conexus.net> wrote:
> 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....(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

Ramon F Herrera

9/14/2009 8:40:00 AM

0

On Sep 14, 4:08 am, Saeed Amrollahi <amrollahi.sa...@gmail.com> wrote:
> On Sep 14, 10:04 am, Ramon F Herrera <ra...@conexus.net> wrote:
>
>
>
> > 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....(Page293, "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


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

Ian Collins

9/14/2009 8:45:00 AM

0

Richard Heathfield wrote:
> 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!

--
Ian Collins

Ian Collins

9/14/2009 8:50:00 AM

0

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?

--
Ian Collins

Ian Collins

9/14/2009 9:30:00 AM

0

Ramon F Herrera wrote:
> On Sep 14, 4:49 am, Ian Collins <ian-n...@hotmail.com> wrote:
>
> > Which compiler/platform are you using?
>
> Linux/g++, of course.

of course? Other platforms and tools do exist you know.

> > 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.

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

--
Ian Collins

Rune Allnor

9/14/2009 11:32:00 AM

0

On 14 Sep, 09:04, Ramon F Herrera <ra...@conexus.net> wrote:

> 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

Richard Heathfield

9/14/2009 1:49:00 PM

0

In <7h6e4oF2qph46U6@mid.individual.net>, Ian Collins wrote:

> Richard Heathfield wrote:
>> 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!

He *did* ask here. He also asked in clc++. I suspect, however, that we
are talking at cross-postoses.

<snip>

> No, not proxy classes, proxies have a different use. What he should
> look up is the PIMPL idiom.

Okay, I believe you.

>> 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!

And if you can do it in C++ with type safety, you can probably do it
in Morse Code, with dots and dashes. :-)

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

Stephen Howe

9/15/2009 12:20:00 AM

0

On Mon, 14 Sep 2009 00:04:54 -0700 (PDT), Ramon F Herrera <ramon@conexus.net> wrote:

>
>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.

Then something is wrong.
It is necessary to declare the private section of a class in the .H file (might be class data and internal private member
functions). It is not necessary to define any of the class private member functions, they can live in a separate 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.

You are confusing declaration with definition.
And it makes no difference whether something is private or public.

I could have

class SomeClass
{
public:
int a; // Bad design to be public
void mfunc1();

private:
int b;
int mfunc2();
int mfunc3() const { return a+b; }
};

in a .H file. mfunc3() is implemented inline. It is both declared and defined.
mfunc1() & mfunc2() are just declarations. Somewhere, the bodies of these functions must be defined if they can be called.

Now the section after "private:" must be in the .H file.
It has to be like that otherwise the compiler has no idea how big a variable of type SomeClass is when defined in a module (like
the one main() is in). But just including the .H file where the class is defined should be enough.

Cheers

Stephen Howe