Topic: Private Methodes declared outside of the class
Author: ben04_01@freenet.de (Ben Strasser)
Date: Sat, 21 Aug 2004 22:19:52 GMT Raw View
James Kuyper wrote:
>>>If you could declare member functions outside the class definition,
>
> anyone could hijack the class (for good or bad purposes), or break the
> class invariants without anyone knowing.
I explained this already several times (including in the original post)
but here goes again. A privat Methode can only be called from a public
or protected one. A method that is public or protected is not private
and therefor has to be in the class declaration. Here's a bit of code:
class A{
int a;
};
void A::foo(){
a=4;
}
int main(){
A a;
//a.foo(); error foo is private
}
>But if it didn't have access to the class's private parts, it wouldn't
>really be a member of that class.
I never said that you wouldn't have access to a class's private parts.
Here is what I suggest:
1)A method can be declared inside a class declaration private, protected
or public. Also it may be declared virtual, static or inline.
2)If a method is not declared inside the class but declared (or defined)
outside of the class it is automaticaly assumed to be private, non
virtual, non static and non inline.
3)The syntax for declaring/defining a method outside of the class is
similar to declaring/defining a normal function except that the name of
the method is preceded by class_name:: .
4)A friend may access all methods that have been declared when the
compiler reaches the definition of the friend. If the friend is a class
then it may access all of the methods that have been declared when the
compiler reaches the definition of the method.
This means the follwing code would work:
class A{
int a;
public:
void do_stuff();
};
void A::foo();
void A::do_stuff(){
foo();
}
void A::foo(){
a=5;
}
and the following:
class B;
class A{
friend class B;
int a;
};
class B{
public:
void do(A&);
}
void A::foo(){
a=5;
}
void B::do(A&a){
a.foo();
}
but not the following:
class A{
int a;
};
void A::foo(){
a=4;
}
int main(){
A a;
//a.foo(); error foo is private
}
the following is ok but does it do anything?:
class A{
int a;
};
void A::foo(){
a=4;
}
int main(){
A a;
}
There's no public or protected method so foo can not be called. (You can
program a hacking functions but you can not execute it.)
With this allowed you can minize the changes that are needed to a header
when the implementation is changed:
//Header
class String{
char*str;
unsigned alloced_chars;
public:
String();
~String();
set_size(unsigned size);
};
//Old implementation unit
String::String():
str(new char[1]),
alloced_chars(1){
str[0]=0;
}
String::~String(){
delete[] str;
}
void String::set_size(unsigned size){
delete[]str;
alloced_chars=size+1;
str=new char[alloced_chars];
str[size]=0;
}
//New implementation
String::String():
str(new char[1000]),
alloced_chars(1000){
str[0]=0;
}
String::~String(){
delete[] str;
}
unsigned String::get_size(){
unsigned size=0;
while(str[size]!=0)
++size;
return size;
}
void String::enlarge(){
unsigned size=get_size();
delete[]str;
alloced_chars*=2;
str=new char[alloced_chars];
str[size]=0;
}
void String::set_size(unsigned new_size){
if(alloced_chars<=new_size)
enlarge();
else
str[new_size]=0;
}
(I know that that string class doesn't copy the string when enlarging
but I want to keep the example small and simple)
And the whole thing without changing a single charachter in the whole
header. Meaning no other implementation unit will be recompiled because
we changed the implementation of the string class. Also the header does
not contain more info than is needed. This makes parsing it a bit faster
and makes it a bit simpler for the eye to read (less useless junk to
ignore).
The alternativ would be to put everything into set_size, so that it
would do more than just one thing and things would start to get messy.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: kuyper@wizard.net (James Kuyper)
Date: Sun, 22 Aug 2004 03:50:17 GMT Raw View
ben04_01@freenet.de (Ben Strasser) wrote in message news:<2opvdhFdeej3U1@uni-berlin.de>...
> James Kuyper wrote:
>
>>>> If you could declare member functions outside the class definition,
>>
>> anyone could hijack the class (for good or bad purposes), or break the
>> class invariants without anyone knowing.
No, I didn't. You might want to be more careful with your attributions.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Sun, 22 Aug 2004 05:16:23 GMT Raw View
"James Kuyper" <kuyper@wizard.net> wrote in message
news:8b42afac.0408200500.48e13c94@posting.google.com...
> SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website
> for Email)") wrote in message news:<2oih41Fb5pb5U1@uni-berlin.de>...
>> "Steve Clamage" <stephen.clamage@sun.com> wrote in message
>> news:cfvuts$sen$1@news1nwk.SFbay.Sun.COM...
>>
>>> Ben Strasser wrote:
>>>
>>>> I was wondering why you can not declare private methods outside of
> the class declaration?
>>>
>>>
>>> If you could declare member functions outside the class definition,
> anyone could hijack the class (for good or bad purposes), or break the
> class invariants without anyone knowing.
>>
>> Well, not if they don't have access to the class' private parts. (I
>> understand this is derailing the discussion from OP's post.)
>
> Then they don't need to be member functions (or even friends).
Very true. However, many a programmer prefers obj.Foo() to Foo(obj), to make
it clear who the "main receiver" is.
A good language would allow both syntaxes making them equivalent (that's
what Cecil does).
(derailing the discussion further...)
Andrei
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: barmar@alum.mit.edu (Barry Margolin)
Date: Sat, 21 Aug 2004 16:43:59 GMT Raw View
In article <2oih41Fb5pb5U1@uni-berlin.de>,
SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See
Website for Email)") wrote:
> "Steve Clamage" <stephen.clamage@sun.com> wrote in message
> news:cfvuts$sen$1@news1nwk.SFbay.Sun.COM...
> > Ben Strasser wrote:
> >>
> >> I was wondering why you can not declare private methods outside of the
> >> class declaration?
> >
> > If you could declare member functions outside the class definition, anyone
> > could hijack the class (for good or bad purposes), or break the class
> > invariants without anyone knowing.
>
> Well, not if they don't have access to the class' private parts. (I
> understand this is derailing the discussion from OP's post.)
But if it didn't have access to the class's private parts, it wouldn't
really be a member of that class.
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: kuyper@wizard.net (James Kuyper)
Date: Sat, 21 Aug 2004 16:46:37 GMT Raw View
SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)") wrote in message news:<2oih41Fb5pb5U1@uni-berlin.de>...
> "Steve Clamage" <stephen.clamage@sun.com> wrote in message
> news:cfvuts$sen$1@news1nwk.SFbay.Sun.COM...
>
>> Ben Strasser wrote:
>>
>>> I was wondering why you can not declare private methods outside of
the class declaration?
>>
>>
>> If you could declare member functions outside the class definition,
anyone could hijack the class (for good or bad purposes), or break the
class invariants without anyone knowing.
>
> Well, not if they don't have access to the class' private parts. (I understand this is derailing the discussion from OP's post.)
Then they don't need to be member functions (or even friends).
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Thu, 19 Aug 2004 04:00:12 GMT Raw View
"Steve Clamage" <stephen.clamage@sun.com> wrote in message
news:cfvuts$sen$1@news1nwk.SFbay.Sun.COM...
> Ben Strasser wrote:
>>
>> I was wondering why you can not declare private methods outside of the
>> class declaration?
>
> If you could declare member functions outside the class definition, anyone
> could hijack the class (for good or bad purposes), or break the class
> invariants without anyone knowing.
Well, not if they don't have access to the class' private parts. (I
understand this is derailing the discussion from OP's post.)
> The existing rule means that the entire class interface is visible in the
> class declaration, and you have a complete list of everything (members and
> friends) that could be affected by an internal implementation change.
>
> This rule works against information hiding, but that was not a design goal
> of C++ classes.
I think that was a reasonable design - to access the private part of a
class, you'd need to touch the header in which the class was defined. Pretty
neat.
What works against information hiding is that lookup precedes protection
check. That arguably is a good thing, but in C++ you can't easily define a
member function that's just totally "hidden".
Andrei
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: jhyslop@ieee.org (Jim Hyslop)
Date: Thu, 19 Aug 2004 04:00:47 GMT Raw View
Steve Clamage wrote:
> Ben Strasser wrote:
>
>>
>> I was wondering why you can not declare private methods outside of the
>> class declaration?
>
>
> If you could declare member functions outside the class definition,
> anyone could hijack the class (for good or bad purposes), or break the
> class invariants without anyone knowing.
That's what I thought at first, but if I understand Ben's proposal,
private member functions not declared in the header can *only* be
declared and defined in a translation unit that contains the definition
of a non-private member. For example:
// file : t_header.h
class T
{
// no private member functions declared
public:
void f();
};
// file : t_impl.cpp
#include "t_header.h"
void T::helper() // OK - this file defines T::f()
{
}
void T::f()
{
}
// file : t_hijacker.cpp
#include "t_header.h"
void T::invader() // error - no non-private members of T
// defined in this file.
{
}
// file : t_hijacker2.cpp
#include "t_header.h"
void T::invader()
{
}
void T::f() // violates ODR
{
}
--
Jim
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: jhyslop@ieee.org (Jim Hyslop)
Date: Thu, 19 Aug 2004 06:16:57 GMT Raw View
Thorsten Ottosen wrote:
> hm...in the code presented earlier I would say friendship is needed.
Depends on your compiler :=)
Recapping the code in question:
> class A
> {
> private:
> int x;
>
> class Impl;
> friend class Impl;
It is not possible to write a well-formed declaration that allows
A::Impl access to A's private members. 11.4 para 1 states "A friend of a
class is a function or class that is not a member of the class ...."
Impl *is* a member of A, therefore A cannot grant it friendship.
Obviously, that's a mistake in the standard. Some compilers get around
the mistake by allowing the friend declaration, some get around it by
implicitly declaring nested classes friends.
DR 45 addresses this by allowing Impl access to all members to which A
has access (this has the effect of making friendship transitive).
--
Jim
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: loic.actarus.joly@wanadoo.fr (=?ISO-8859-1?Q?Lo=EFc_Joly?=)
Date: Thu, 19 Aug 2004 15:49:23 GMT Raw View
Steve Clamage wrote:
> Ben Strasser wrote:
>=20
>>
>> I was wondering why you can not declare private methods outside of the=
=20
>> class declaration?
>=20
>=20
> If you could declare member functions outside the class definition,=20
> anyone could hijack the class (for good or bad purposes), or break the=20
> class invariants without anyone knowing.
Not if you can write only private non-virtual functions outside of the=20
class : Sure you could add functions to the class, but nobody except the=20
implementation of the class would be able to call them.
> The existing rule means that the entire class interface is visible in=20
> the class declaration, and you have a complete list of everything=20
> (members and friends) that could be affected by an internal=20
> implementation change.
>=20
> This rule works against information hiding, but that was not a design=20
> goal of C++ classes.
I'm not sure what you do mean by hiding here. If you mean hiding to=20
human, I do not care. If you mean hiding from all the code using a class=20
that something internal to this class has been changed, I think it would=20
be worthwile.
It could even lead to header files being more "write protected" than=20
implementation files.
There are currently alternatives :
- PIMPL : Has an overhead, requires some changes in the class definition=20
to switch from a non-pimpl to a pimpl class. It can still be usefull for=20
private data, and for hiding to the human.
- Use only free functions for implementation, pass them all they need in=20
argument : That make function with long argument lists, which are a pain=20
to write and a pain to use.
Although I understand the current rules for data, or for virtual,=20
protected of public functions, I believe it would be really easy to=20
relax those rules for private-non virtual functions.
--=20
Lo=EFc
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: ben04_01@freenet.de (Ben Strasser)
Date: Thu, 19 Aug 2004 18:39:09 GMT Raw View
Steve Clamage wrote:
> If you could declare member functions outside the class definition,
> anyone could hijack the class (for good or bad purposes), or break the
> class invariants without anyone knowing.
No, you can't if you can only declare private methods outside of the
class as I already explained. You can declare and define a private
method anywhere but only call it from a public/protected method which is
part of the interface an therefor has to be declared in the class. A
hacking function which can not be called is no danger.
And even if it was possible if the user of the class knows it's data
member (even if they are private) he can access them from anywhere using
some pointer casts and assuming the internal representation of the
class. So you will have to use pImpl or C's handle approach if you
really want to stop people from breaking in.
Andrei Alexandrescu
> What works against information hiding is that lookup precedes
> protection check. That arguably is a good thing, but in C++
> you can't easily define a member function that's just totally
> "hidden".
Why not? I don't see a syntactical problem, I don't see a technical
problem, I don't see a risk of breaking encapsulation.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: nesotto@cs.auc.dk ("Thorsten Ottosen")
Date: Wed, 18 Aug 2004 17:11:21 GMT Raw View
"Ben Strasser" <ben04_01@freenet.de> wrote in message news:2oco5cF9dtbhU1@uni-berlin.de...
| Thorsten Ottosen wrote:
| > ""Conrad Weyns"" <weyns@online.no> wrote in message
| news:_p6Uc.1281$g%5.16328@news2.e.nsc.no...
| > >
| > > "Ben Strasser" <ben04_01@freenet.de> wrote in message
| > > news:2oblfaF8nds3U1@uni-berlin.de...
| > > > Hello,
| > > >
| > > > I was wondering why you can not declare private methods outside
| of the
| > > > class declaration?
| >
| > because it's not needed.
|
| And why is it not needed?
as I said, you can use static function in the implementation file?
| > > As Bob said, the Pimpl idiom will help you out.
| > > But you can often get away with mere static functions.
| > > All you need is to declare friendship:
| >
| >Actually friendship is not even needed. just add functions with
| >appropriate arguments
| >in the implementation file.
|
| So how do you do inheritance?
Depends on what you mean. If you want to call a protected function you have to do something
(assuming you have spread the implementation of the class hierarchy over several translation units).
For example, given
// foo.hpp
struct Foo { ... };
struct Bar { ... };
create
// foo_private.hpp
void some_private_substitute( int& t );
void some_other( map<int>& m );
and include foo_private.hpp in the necessary translation-units.
| The pImpl is not bad as a workaround but it is and stays a workaround to
| replace a missing feature.
I have used the Pimpl-idiom a lot, but looking back I think I wish I had done as described above. Afterall, state-changes
are much less common than adding a private/protected function.
br
Thorsten
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Wed, 18 Aug 2004 17:17:28 GMT Raw View
In article <2oco5cF9dtbhU1@uni-berlin.de>, Ben Strasser
<ben04_01@freenet.de> writes
>And why is it not needed? Because there's a workaround which allows you
>to do a simple thing the hard way?
>
>PImpl adds extra indirections, which are slower than when using a C
>interface (compare this->imp->data to handle->data) but worse is the
>extra indirection in the source code which makes you have to actually
>think that imp->imp_foo() is actually calling a member of the same class.
Which, AFAICS, any reasonable quality compiler can optimise away.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: stephen.clamage@sun.com (Steve Clamage)
Date: Thu, 19 Aug 2004 01:30:44 GMT Raw View
Ben Strasser wrote:
>
> I was wondering why you can not declare private methods outside of the
> class declaration?
If you could declare member functions outside the class definition,
anyone could hijack the class (for good or bad purposes), or break the
class invariants without anyone knowing.
The existing rule means that the entire class interface is visible in
the class declaration, and you have a complete list of everything
(members and friends) that could be affected by an internal
implementation change.
This rule works against information hiding, but that was not a design
goal of C++ classes.
---
Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: nesotto@cs.auc.dk ("Thorsten Ottosen")
Date: Thu, 19 Aug 2004 01:39:34 GMT Raw View
""Conrad Weyns"" <weyns@online.no> wrote in message news:KmgUc.1340$g%5.17394@news2.e.nsc.no...
|
| ""Thorsten Ottosen"" <nesotto@cs.auc.dk> wrote in message
| news:41211964$0$73936$14726298@news.sunsite.dk...
| > ""Conrad Weyns"" <weyns@online.no> wrote in message
| news:_p6Uc.1281$g%5.16328@news2.e.nsc.no...
| > |
| > | "Ben Strasser" <ben04_01@freenet.de> wrote in message
| > | As Bob said, the Pimpl idiom will help you out.
| > | But you can often get away with mere static functions.
| > | All you need is to declare friendship:
| >
| > Actually friendship is not even needed. just add functions with
| appropriate arguments
| > in the implementation file.
|
| I just tried this and I stand corrected. I am surprised.
| I allways thought that declaring a Impl class this way was identical to a
| nested class.
| Evidently, it isn't and I must admit I don't understand why.
hm...in the code presented earlier I would say friendship is needed. But my point was that
it's pointless to create static function inside A::Impl. Those functions can be static functions
taking eg. an int& instead of an A&.. So instead of
class A::Impl
{
public:
static int f(A& a)
{
return a.x + 123;
}
};
we should write
int f( int a_x ) { return ax + 123: }
br
Thorsten
br
Thorsten
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: ben04_01@freenet.de (Ben Strasser)
Date: Mon, 16 Aug 2004 14:48:32 GMT Raw View
Hello,
I was wondering why you can not declare private methods outside of the
class declaration?
When you write a C like interface, you declare the functions inside a
header and implement them inside a compilation unit. These functions may
get big and therefore it's a good idea to spilt them up into a few
helper functions. These helpers are not part of the interface and
therefore they are often static or in a namespace{} block. If the
implementation of the functions change, some helper functions may no
longer be needed or new ones are added. This is no problem because they
are not declared in the header and therefore no other compilation units
knows about them and therefore do not need to be recompiled.
Now when you are writing a C++ like interface (meaning a class) you put
the declaration of the class and it's members inside the header. If they
are public or protected they need to be there because those members are
part of the interface. Private members are not part of the interface but
part of the implementation, so other compilation units shouldn't know
about them. They although have to know about data members because they
need to know the total size of the class. Private methods although don't
affect the size, so why are they there.
There are few situation where they have to be in the header. For example
if they are virtual, or a friend of the class uses them or when a public
inline method uses them. But what about plain ordinary helper methods
for plain ordinary public methods which are defined in the
implementation unit? These don't have to be known in each compilation
unit that includes the header.
They even force recompilation when one is not needed. If the
implementation of a class is changed but the data members, the public
and protected methods stay the same then there is no need to recompile
every unit that uses that class. If the implementation changes it is
likely that new other helper methods are needed, these although are
declared in the header so the header file has to be changed. Now the
date of the last modification to the header file is changed and when
compiling again, the compiler will think that the class has really been
changed (because of the date of the header file) and recompile
everything that includes that header.
So why not allow something like:
//header
class A{
public:
void do_stuff();
};
//cpp
void A::helper(){
//...
}
void A::do_stuff(){
//...
helper();
//...
}
helper has not been declared in the declaration of A so it is
automatically assumed to be private. This wouldn't allow to break into
the class in an other compilation unit, you can declare and define a
private method everywhere although you can only call it from a protected
/ public method which has to be declared in the class declaration.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: invalid@bigfoot.com (Bob Hairgrove)
Date: Mon, 16 Aug 2004 16:42:57 GMT Raw View
On Mon, 16 Aug 2004 14:48:32 GMT, ben04_01@freenet.de (Ben Strasser)
wrote:
>Hello,
>
>I was wondering why you can not declare private methods outside of the
>class declaration?
>
>When you write a C like interface, you declare the functions inside a
>header and implement them inside a compilation unit. These functions may
>get big and therefore it's a good idea to spilt them up into a few
>helper functions. These helpers are not part of the interface and
>therefore they are often static or in a namespace{} block. If the
>implementation of the functions change, some helper functions may no
>longer be needed or new ones are added. This is no problem because they
>are not declared in the header and therefore no other compilation units
>knows about them and therefore do not need to be recompiled.
>
>Now when you are writing a C++ like interface (meaning a class) you put
>the declaration of the class and it's members inside the header. If they
>are public or protected they need to be there because those members are
>part of the interface. Private members are not part of the interface but
>part of the implementation, so other compilation units shouldn't know
>about them. They although have to know about data members because they
>need to know the total size of the class. Private methods although don't
>affect the size, so why are they there.
>
>There are few situation where they have to be in the header. For example
>if they are virtual, or a friend of the class uses them or when a public
>inline method uses them. But what about plain ordinary helper methods
>for plain ordinary public methods which are defined in the
>implementation unit? These don't have to be known in each compilation
>unit that includes the header.
>
>They even force recompilation when one is not needed. If the
>implementation of a class is changed but the data members, the public
>and protected methods stay the same then there is no need to recompile
>every unit that uses that class. If the implementation changes it is
>likely that new other helper methods are needed, these although are
>declared in the header so the header file has to be changed. Now the
>date of the last modification to the header file is changed and when
>compiling again, the compiler will think that the class has really been
>changed (because of the date of the header file) and recompile
>everything that includes that header.
>
>So why not allow something like:
>
>//header
>class A{
>public:
> void do_stuff();
>};
>//cpp
>void A::helper(){
> //...
>}
>void A::do_stuff(){
> //...
> helper();
> //...
>}
>
>helper has not been declared in the declaration of A so it is
>automatically assumed to be private. This wouldn't allow to break into
>the class in an other compilation unit, you can declare and define a
>private method everywhere although you can only call it from a protected
>/ public method which has to be declared in the class declaration.
>
Currently, this can be achieved using what is often called the "pImpl
idiom" ("pointer to implementation"). I'm not sure who first came up
with this name, but I believe it was Herb Sutter.
You can store a pointer to a different type, which is merely forward
declared, in your "visible" class header file, for example:
// Foo.h:
class FooImpl;
class Foo {
public:
// your interface functions here...
private:
FooImpl * pImpl;
};
FooImpl implements all of the private helper functions which would
otherwise be members of Foo. You #include "FooImpl.h" in your
"Foo.cpp" file, not in "Foo.h".
This greatly helps reduce client compilation dependencies when the
helper implementation needs to change, but the interface can stay the
same.
--
Bob Hairgrove
NoSpamPlease@Home.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: weyns@online.no ("Conrad Weyns")
Date: Mon, 16 Aug 2004 18:09:59 GMT Raw View
"Ben Strasser" <ben04_01@freenet.de> wrote in message
news:2oblfaF8nds3U1@uni-berlin.de...
> Hello,
>
> I was wondering why you can not declare private methods outside of the
> class declaration?
>
> When you write a C like interface, you declare the functions inside a
> header and implement them inside a compilation unit. These functions may
[]
> So why not allow something like:
>
> //header
> class A{
> public:
> void do_stuff();
> };
> //cpp
> void A::helper(){
> //...
> }
> void A::do_stuff(){
> //...
> helper();
> //...
> }
As Bob said, the Pimpl idiom will help you out.
But you can often get away with mere static functions.
All you need is to declare friendship:
----- A.hpp -----
class A
{
private:
int x;
class Impl;
friend class Impl;
public:
A(int i_x) ;
int f();
};
----- A.cpp ----
class A::Impl
{
public:
static int f(A& a)
{
return a.x + 123;
}
};
int A::f()
{
return Impl::f(*this);
}
-----------
Regards,
Conrad Weyns
>
> helper has not been declared in the declaration of A so it is
> automatically assumed to be private. This wouldn't allow to break into
> the class in an other compilation unit, you can declare and define a
> private method everywhere although you can only call it from a protected
> / public method which has to be declared in the class declaration.
>
> ---
> [ comp.std.c++ is moderated. To submit articles, try just posting with ]
> [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
> [ --- Please see the FAQ before posting. --- ]
> [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: ben04_01@freenet.de (Ben Strasser)
Date: Mon, 16 Aug 2004 19:20:56 GMT Raw View
> Currently, this can be achieved using what is often called the "pImpl
> idiom" ("pointer to implementation"). I'm not sure who first came up
> with this name, but I believe it was Herb Sutter.
>
> You can store a pointer to a different type, which is merely forward
> declared, in your "visible" class header file, for example:
>
> // Foo.h:
> class FooImpl;
> class Foo {
> public:
> // your interface functions here...
> private:
> FooImpl * pImpl;
> };
>
> FooImpl implements all of the private helper functions which would
> otherwise be members of Foo. You #include "FooImpl.h" in your
> "Foo.cpp" file, not in "Foo.h".
>
> This greatly helps reduce client compilation dependencies when the
> helper implementation needs to change, but the interface can stay the
> same.
The pImpl idiom is a workaround (although I personally prefer a C
> interface with a C++ wrapper because that has the good side effect that
> when put in a dll you can easily interface with C or any other language)
> but I was wondering why C++ doesn't allow hiding those parts of the
> implementation that don't need to be known in the first place.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: nesotto@cs.auc.dk ("Thorsten Ottosen")
Date: Mon, 16 Aug 2004 20:38:10 GMT Raw View
""Conrad Weyns"" <weyns@online.no> wrote in message news:_p6Uc.1281$g%5.16328@news2.e.nsc.no...
|
| "Ben Strasser" <ben04_01@freenet.de> wrote in message
| news:2oblfaF8nds3U1@uni-berlin.de...
| > Hello,
| >
| > I was wondering why you can not declare private methods outside of the
| > class declaration?
because it's not needed.
| As Bob said, the Pimpl idiom will help you out.
| But you can often get away with mere static functions.
| All you need is to declare friendship:
Actually friendship is not even needed. just add functions with appropriate arguments
in the implementation file.
br
Thorsten
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: ben04_01@freenet.de (Ben Strasser)
Date: Wed, 18 Aug 2004 05:31:38 GMT Raw View
Thorsten Ottosen wrote:
> ""Conrad Weyns"" <weyns@online.no> wrote in message
news:_p6Uc.1281$g%5.16328@news2.e.nsc.no...
> >
> > "Ben Strasser" <ben04_01@freenet.de> wrote in message
> > news:2oblfaF8nds3U1@uni-berlin.de...
> > > Hello,
> > >
> > > I was wondering why you can not declare private methods outside
of the
> > > class declaration?
>
> because it's not needed.
And why is it not needed? Because there's a workaround which allows you
to do a simple thing the hard way?
PImpl adds extra indirections, which are slower than when using a C
interface (compare this->imp->data to handle->data) but worse is the
extra indirection in the source code which makes you have to actually
think that imp->imp_foo() is actually calling a member of the same class.
To be able to call a public (or inherited protected get function) you
also need to make all functions in the Implementation static and pass
them manually the this pointer (so that you can access the protected
members of the base class). Now we have passed_this->imp->data and
imp->imp_foo(this) standing in the actual source code. Not quiet my
definition of readable code.
Ok we could leave the private methods non static but then 2 pointers
will be passed to each call => again a slowdown compared to C (wasn't
C++ supposed to be a combination of C's speed with OO?).
> > As Bob said, the Pimpl idiom will help you out.
> > But you can often get away with mere static functions.
> > All you need is to declare friendship:
>
>Actually friendship is not even needed. just add functions with
>appropriate arguments
>in the implementation file.
So how do you do inheritance?
The pImpl is not bad as a workaround but it is and stays a workaround to
replace a missing feature.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: weyns@online.no ("Conrad Weyns")
Date: Wed, 18 Aug 2004 05:32:11 GMT Raw View
""Thorsten Ottosen"" <nesotto@cs.auc.dk> wrote in message
news:41211964$0$73936$14726298@news.sunsite.dk...
> ""Conrad Weyns"" <weyns@online.no> wrote in message
news:_p6Uc.1281$g%5.16328@news2.e.nsc.no...
> |
> | "Ben Strasser" <ben04_01@freenet.de> wrote in message
> | news:2oblfaF8nds3U1@uni-berlin.de...
> | > Hello,
> | >
> | > I was wondering why you can not declare private methods outside of the
> | > class declaration?
>
> because it's not needed.
>
> | As Bob said, the Pimpl idiom will help you out.
> | But you can often get away with mere static functions.
> | All you need is to declare friendship:
>
> Actually friendship is not even needed. just add functions with
appropriate arguments
> in the implementation file.
I just tried this and I stand corrected. I am surprised.
I allways thought that declaring a Impl class this way was identical to a
nested class.
Evidently, it isn't and I must admit I don't understand why. A nested class
would need friendship.
Thanks for putting me right!
Regards,
Conrad Weyns
>
> br
>
> Thorsten
>
>
> ---
> [ comp.std.c++ is moderated. To submit articles, try just posting with ]
> [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
> [ --- Please see the FAQ before posting. --- ]
> [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]