public headers

I

iesvs

Hello,
i want to create c++ libraries (for my use) but I don't know how I
must do to have headers which contain only the public declarations.
I used in C to put the private declarations in *.c and the public
declaration in *.h. But how to do that in c++.
If someone could help me, he would be nice.
Thank you.
 
V

Victor Bazarov

i want to create c++ libraries (for my use) but I don't know how I
must do to have headers which contain only the public declarations.
I used in C to put the private declarations in *.c and the public
declaration in *.h. But how to do that in c++.
If someone could help me, he would be nice.

What difference do you think exists between C and C++ in that
respect? Put your public declarations in .h files, put your private
declarations and definitions in .cpp. Now, don't let the presence
of 'public' and 'private' access specifiers confuse you. Those are
not what you used to have in C (as I understand it), those are to
prevent errors, not really to protect your intellectual property.

V
 
A

Alf P. Steinbach

* (e-mail address removed):
i want to create c++ libraries (for my use) but I don't know how I
must do to have headers which contain only the public declarations.
I used in C to put the private declarations in *.c and the public
declaration in *.h. But how to do that in c++.

You can do the same in C++.

However, instead of using "static" to make things private in a
compilation unit, you should consider an anonymous namespace (in the
implementation file), i.e. instead of

static void foo() { doTheTangoAndMore(); }

think about writing

namespace
{
void foo() { doTheTangoAndMore(); }
}

The difference is that the latter version has extern linkage yet won't
clash with functions named foo in other compilation units.

In particular, for a class that's only used in the implementation
there's no other way, because you can't use "static" on a class.

Also, using "static" on data is deprecated, and won't necessarily be
supported by future C++ compilers, whereas anonymous namespaces will work.

For the innards of a class that's exposed to client code (i.e. defined
in a header) you can use the "private", "protected" and "public" access
specifiers, which you can read about in any good C++ textbook.

Where you need physical hiding (e.g. avoid exposing dirty headers that
you use, to client code) you can use the PIMPL idiom, which you can find
explained in dozens or hundreds of articles on the net, including
postings in this group -- but you probably don't need that just yet.

Cheers, & hth.,

- Alf
 
I

iesvs

What difference do you think exists between C and C++ in that
respect?
Many.

Put your public declarations in .h files, put your private
declarations and definitions in .cpp.

Yeah but I mean I got a class with private and public members and I
just want the public appear in headers not private.
Now, don't let the presence
of 'public' and 'private' access specifiers confuse you. Those are
not what you used to have in C (as I understand it), those are to
prevent errors, not really to protect your intellectual property.

I know it, I just think that if a member is private it must not be
present in headers.
 
R

robertwessel2

I know it, I just think that if a member is private it must not be
present in headers.


That's incorrect. It must be in the header or the compiler will not
be able to create the object correctly, since it has to create ("new")
any instances with the space for the private items in the correct
spots.

If you really want to hide those details, you need to implement an
abstract base class, or something along those lines.
 
I

iesvs

That's incorrect. It must be in the header or the compiler will not
be able to create the object correctly, since it has to create ("new")
any instances with the space for the private items in the correct
spots.

If you really want to hide those details, you need to implement an
abstract base class, or something along those lines.

I know now why I refuse for many years to develop in c++. It confirms
what I thought. I get back to C.
 
S

Scott Gifford

[...]
I know it, I just think that if a member is private it must not be
present in headers.

Note that while the compiler needs to know the types and sizes of the
objects, it doesn't need to know their names. If your goal is to
hide the internal workings of your code, you could certainly change:

private:
int secretNumber;
MasterKey *key;
double doubleSecret;

to:

private:
int adfoiwjeofijasdoijfaoeiwjpowiejapwoei;
void *oaisjpoijpj8p9ja89jjdlskjvas8vap9e8jw;
double ap98fjas98ejfpzs9vzd8a9pwe89pwejrp98awj98awjef;

when you distribute the code. This form of obfuscation is common in
Java and Javascript, and tools area available to do the conversion
automatically. I haven't come across any for C++, but they may exist,
and if not it wouldn't be too hard to write a simple one.

This will hide your private variables about as well as you can
reasonably expect; after all, the contents of those variables are
readily available to anybody with a debugger.

Hope this helps,

----Scott.
 
I

iesvs

How do you do this in C?

####################

//list.c

struct list
{
int *hd;
LIST *tl;
}

int *get_hd_unsafe (LIST *l) //private for example
{
return l->hd;
}

int get_hd (LIST *l) //public for example
{
if (l == NULL)
return NULL;
get_hd_unsafe (l);
}

#####################

//list.h

typedef struct list LIST;

int get_hd (LIST *);
 
A

Adam Nielsen

//list.c
struct list
{
int *hd;
LIST *tl;
}

int *get_hd_unsafe (LIST *l) //private for example
{
return l->hd;
}

int get_hd (LIST *l) //public for example
{
if (l == NULL)
return NULL;
get_hd_unsafe (l);
}

#####################

//list.h

typedef struct list LIST;

int get_hd (LIST *);

But those public and private functions are global - when you combine
them into a class, it's like using a struct - how would you do this in C?
> struct list
> {
> int *hd; // make this private
> LIST *tl; // make this public
> }

That's the problem from a C++ point of view - you have one complete
structure but you want to hide part of it - it's not possible in C or C++.

Of course you might be looking at this the wrong way. Why do you want
to hide the private members in your classes? Anyone using the class
won't be able to access them because they're private, but what if
someone wants to extend one of your classes to enhance it? If all the
data members are hidden (as opposed to being declared as protected),
then you could limit the usefulness of your classes, by preventing
people from expanding them.

Cheers,
Adam.
 
I

iesvs

That's the problem from a C++ point of view - you have one complete
structure but you want to hide part of it - it's not possible in C or C++.

What does my example ?
Of course you might be looking at this the wrong way. Why do you want
to hide the private members in your classes?

Because when someone (me for example) want to use the library he reads
the .h (or .hpp with c++) and he know which objects (struct) exist and
which function exist (an API reference), I don't want him to see a
function that he hasn't to use. If he want to use an internal
function, he can but it's his problem, not mine.
but what if
someone wants to extend one of your classes to enhance it? If all the
data members are hidden (as opposed to being declared as protected),

I don't use protected (it's useless). I don't want him to know how
work my class in internal, because it could change if I use a new
method (new algorithm, I change an int into a char etc.), but I never
change the public (it's a fundamental principle). And I don't want him
to see the internal of my class. I'm a part of guys who think that
look at the source code of others is heretical.
 
A

Adam Nielsen

What does my example ?

See the question in my last message - how would you make 'hd' private
and 'tl' public, while leaving them all inside struct 'list'?
Because when someone (me for example) want to use the library he
reads the .h (or .hpp with c++) and he know which objects (struct)
exist and which function exist (an API reference), I don't want him
to see a function that he hasn't to use. If he want to use an
internal function, he can but it's his problem, not mine.

This isn't how programming languages generally work, they're not
supposed to be closed because let's face it, a bunch of text files isn't
really that secure. If someone is determined to see how your code works
they'll figure it out eventually. Hiding code like this will only trick
you into thinking it's secure.
I don't use protected (it's useless).

I find it quite useful myself. I suspect you've never come across a
problem that could be solved with the use of protected members :)
I don't want him to know how work my class in internal, because it
could change if I use a new method (new algorithm, I change an int
into a char etc.), but I never change the public (it's a fundamental
principle).

This is the whole idea behind private members. You're not supposed to
use them because they could change without warning. It doesn't matter
whether you can see them or not, only a foolish programmer would
'illegally' use somebody else's private data members. It's like an
honesty system - you're telling people not to use the private members,
and if they go ahead and use them, then it's their own fault when you
change something and their code breaks. Serves them right for ignoring
you :)
And I don't want him to see the internal of my class. I'm a part of
guys who think that look at the source code of others is heretical.

Then I feel sorry for you :) Sharing source code is amazingly
productive, you can learn a huge amount from reading someone else's
code. Not sharing source code is like painting an amazing picture and
then refusing to show it to anyone - how can people respect your skill
as a programmer if they can't see your code?

If you don't want people to see your code, then the safest way is to
simply not write any classes - that's the only way you can guarantee
that nobody will see your code ;-)

(or you could use abstract base classes, as has already been suggested:
http://www.parashift.com/c++-faq-lite/abcs.html)

Cheers,
Adam.
 
I

iesvs

See the question in my last message - how would you make 'hd' private
and 'tl' public, while leaving them all inside struct 'list'?

I never put variables in public area. I always create function to
access the variables. I learnt with an object language where the
variables are private (no choice).
This isn't how programming languages generally work, they're not
supposed to be closed because let's face it, a bunch of text files isn't
really that secure. If someone is determined to see how your code works
they'll figure it out eventually. Hiding code like this will only trick
you into thinking it's secure.

I don't want to hide my code (it's technologically impossible, even
with a binary, which is a source code for the system's language). I
just want to give a complete API in .h, someone using it doesn't need
to look inside the .c, but if he wants (Why ? I don't know) he can.
I find it quite useful myself. I suspect you've never come across a
problem that could be solved with the use of protected members :)

I use public method, it works. I think that if a derived class could
use a method, anything else must. I find the opposite weird.
It doesn't matter

It matters, it's not clean. Have you ever seen in an API the library's
interior ? Me, never.
whether you can see them or not, only a foolish programmer would
'illegally' use somebody else's private data members

I made it sometimes, but temporary.
. It's like an
honesty system - you're telling people not to use the private members,
and if they go ahead and use them, then it's their own fault when you
change something and their code breaks. Serves them right for ignoring
you :)

We agree.
Then I feel sorry for you :) Sharing source code is amazingly
productive, you can learn a huge amount from reading someone else's
code. Not sharing source code is like painting an amazing picture and
then refusing to show it to anyone - how can people respect your skill
as a programmer if they can't see your code?

I share source code for the reasons you said, and others (portability,
which is nearly impossible with binaries). But I think that if someone
want to use my libraries he just has to read the .h (which are here
for that in my opinion).
And personally I respect the skill of someone as a programmer when I
don't have to read his .c to understand how works his library and just
have to read the .h. Each time I respect someone for those reasons,
when I take a look inside his code I find it marvelous, because when a
guy is clean at exterior he is always clean inside (but it's very
rare).
(or you could use abstract base classes, as has already been
suggested:http://www.parashift.com/c++-faq-lite/abcs.html)

Not so good in my opinion.
 
G

Guest

I don't want to hide my code (it's technologically impossible, even
with a binary, which is a source code for the system's language). I
just want to give a complete API in .h, someone using it doesn't need
to look inside the .c, but if he wants (Why ? I don't know) he can.

You really should not confuse the header files with the documentation of
the API, they should be separate, even if it is just by generating the
documentation from the source via doxygen or similar tools. Neither C
not C++ is expressive enough to accurately describe an interface (such
as pre- and post-conditions, invariants, etc.) with just the the
information usually found in a header file.
 
I

iesvs

You really should not confuse the header files with the documentation of
the API, they should be separate, even if it is just by generating the
documentation from the source via doxygen or similar tools. Neither C
not C++ is expressive enough to accurately describe an interface (such
as pre- and post-conditions, invariants, etc.) with just the the
information usually found in a header file.

Why not ? It's possible to describe a library with the headers. When
the developer make his library, he puts the information for the use in
comment of the header file.
I come from a language where looking the header files teach you
everything you need to use standard libraries.

And with your way of making libraries, we got this : you got a library
V2.0 but the API reference doesn't exist for the V1.0, and it's very
frequent (less currently the geeks have matured).
 
J

James Kanze

Why not ? It's possible to describe a library with the headers. When
the developer make his library, he puts the information for the use in
comment of the header file.
I come from a language where looking the header files teach you
everything you need to use standard libraries.

That's completely false, since it's not true for any language.
Headers are meant for the compiler, documentation for human
readers, and the two readers have a different set of constraints
and expectations.

In a good organization, typically, you're write the
documentation first, then generate (part of) the headers from
it. Failing this (and far more common), you'll write the
documentation in the form of (extractable) comments, then add
whatever extra stuff the compiler requires; the documentation
tool then extracts and formats the original comments. This is
possible in both C and C++; C++ allows considerably more
options, however, with regards to how to do it.

The classical C idiom which you showed, for example, requires
all objects to be allocated dynamically, and for the user to
explicitly free them; in C++, the compilation firewall idiom
does the same thing, except that the object can easily be made
to act like a pure value type, which manages the lifetime of the
actual implementation data itself. And if performance
considerations mean that the dynamic allocation has to go, then
in C++, you can at least declare the data elements private,
where as in C, there's no way you can prevent client code from
depending on them.
 
G

Guest

Why not ? It's possible to describe a library with the headers. When
the developer make his library, he puts the information for the use in
comment of the header file.
I come from a language where looking the header files teach you
everything you need to use standard libraries.

And with your way of making libraries, we got this : you got a library
V2.0 but the API reference doesn't exist for the V1.0, and it's very
frequent (less currently the geeks have matured).

I am not sure I quite understood the last part. Are you claiming that
keeping the documentation separate from the header files will
unavoidably result in lack of documentation? That is not true, a lack of
documentation is because lack of discipline and methodology.


By the way, I think that some of your problems comes from a C background
where a user of a library includes one header defining a few structs and
some functions that represent the whole interface to the library. In C++
it is more common with class libraries where each header provides only
one or a few classes, if more classes are required you have to include
some other header files. In C++ the interface to a library often is the
classes themselves.
 
I

iesvs

I am not sure I quite understood the last part. Are you claiming that
keeping the documentation separate from the header files will
unavoidably result in lack of documentation?

Not unavoidably. And now it's more easy to find reference than in the
past. But in the past, yes the documentation were often missing (like
the libraries for the socket, there was a cast for the address that
you had to invent, what is a sockaddr, I seek for it but I still don't
find, incidentally if someone knows ?).
That is not true, a lack of
documentation is because lack of discipline and methodology.

Yes, but geeks have often a lack of discipline.
In C++ the interface to a library often is the
classes themselves.

No, hardly ever, a private thing is not a part of the interface.
 
V

Victor Bazarov

No, hardly ever, a private thing is not a part of the interface.

A private thing is the interface for itself and friends. So,
technically it *is* part of the interface. Unless, of course,
it's data. Then it's part of the object state.

V
 
I

iesvs

A private thing is the interface for itself and friends. So,
technically it *is* part of the interface.

The interface is by definition for the exterior so not for the class
itself. And Like I don't use protected I don't use friend, in my
opinion protected and friend are hacks (a bandage if this is not use
like this in English) create for those who don't know how to use
objects.

I specify I'm a fundamentalist, this is why I just use public and
private, don't use virtual except for the pure virtual (virtual ... =
0) and don't want a private member appears in headers. So don't be
surprised if I got strange ideas.
 

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
474,201
Messages
2,571,048
Members
47,647
Latest member
NelleMacy9

Latest Threads

Top