public headers

G

Guest

The interface is by definition for the exterior so not for the class
itself.

Since the private members are needed when instantiating an object in the
users's code they must by definition be part of the interface (the
user's code is the exterior you are talking about).
 
V

Victor Bazarov

The interface is by definition for the exterior

By whose definition? And what is exterior? As far as I'm concerned,
anything exterior to an instance (even another instance of the same
class) should require some kind of interface. Blindly allowing some
class instances to meddle with other instances' private data is not
necessary the RIGHT THING TO DO(tm).
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.

Fine. You can live with your "opinion" that interface is the public
member functions only. It doesn't make it right, but you're entitled
to your opinion.
I specify I'm a fundamentalist, [..] So don't be
surprised if I got strange ideas.

As long as you don't go around blowing up World Trade Centers, I have
no problem with your fundamentalism (in C++ or otherwise). As to your
ideas, if even you specify them as "strange", why do you have them?
Get rid of them, or change them, to become normal in your own view.

V
 
B

Ben Rudiak-Gould

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

I haven't read this whole back-and-forth, but I totally understand where
iesvs is coming from here. I've often wished I could declare just the public
part of a class in a header, and the private part elsewhere. And there's no
deep reason I shouldn't be able to do that; it's just a missing language
feature. C++ already supports incomplete struct/class types, which
correspond to the special case where everything is hidden. It could just as
well support partially complete types. I can even think of a reasonably
intuitive syntax for it that doesn't require any new keywords:

// header

class A {
public:
float f;
void method();
... // <- that's a literal '...'
};

// private implementation

class A : public Base {
public:
float f; // must match (enforced by implementation)
void method();
private:
int x;
};

void A::method() { ... }

The current syntax "class A;" would be identical to "class A { ... };".

I suspect, though, that if I proposed this to the standards committee,
they'd say "use virtual functions". And indeed you can get exactly the same
effect with virtual functions:

// header

class A {
public:
float f;
virtual void method() = 0;
};

// private implementation

class A_impl : public A, public Base {
public:
void method();
private:
int x;
};

void A_impl::method() { ... }

So this is what I recommend to the original poster. As far as I can tell, it
does exactly what you want. The only advantage of incomplete class
declarations would be efficiency: in a typical implementation they'd save
you a machine word per object and a hard-to-predict indirect jump per method
call.

-- Ben
 
I

iesvs

// header
class A {
public:
float f;
virtual void method() = 0;
};

// private implementation

class A_impl : public A, public Base {
public:
void method();
private:
int x;
};

Some have already suggested that (I think).
I don't want to create a new class (A_impl) to do that. It's a hack
and I refuse hacks, I'm too fundamentalist for that.
 
J

James Kanze

I haven't read this whole back-and-forth, but I totally
understand where iesvs is coming from here. I've often wished
I could declare just the public part of a class in a header,
and the private part elsewhere. And there's no deep reason I
shouldn't be able to do that; it's just a missing language
feature.

In a way, yes. On the other hand, supporting this would create
very serious implementation problems. Perhaps if you find a
reasonable way to implement it, it could be adopted; at present,
the best compiler experts I know don't consider it implementable
(while still allowing value semantics, of course).
C++ already supports incomplete struct/class types, which
correspond to the special case where everything is hidden. It
could just as well support partially complete types.

If they had the same restrictions as incomplete types, maybe.
But then, you'd need to define a special syntax, etc., to define
them. And what does it buy you? What can you do with them that
you can't already do with incomplete types.
I can even think of a reasonably intuitive syntax for it that
doesn't require any new keywords:
// header

class A {
public:
float f;
void method();
... // <- that's a literal '...'
};
// private implementation
class A : public Base {
public:
float f; // must match (enforced by implementation)
void method();
private:
int x;
};
void A::method() { ... }
The current syntax "class A;" would be identical to "class A { ... };".
I suspect, though, that if I proposed this to the standards
committee, they'd say "use virtual functions". And indeed you
can get exactly the same effect with virtual functions:
// header
class A {
public:
float f;
virtual void method() = 0;
};
// private implementation
class A_impl : public A, public Base {
public:
void method();
private:
int x;
};
void A_impl::method() { ... }

Exactly.

Note that if you allow declaring instances of the "partially
complete" class A, you run into serious implementation problems.
And if you don't, your partially complete class doesn't provide
any advantage with respect to the above.
So this is what I recommend to the original poster. As far as
I can tell, it does exactly what you want. The only advantage
of incomplete class declarations would be efficiency: in a
typical implementation they'd save you a machine word per
object and a hard-to-predict indirect jump per method call.

And the compilation firewall idiom allows replacing the virtual
function call with a non-virtual one (but imposes an additional
indirection on the data accesses, or a second function call).

This is, perhaps, the reason why C++ does things the way it
does. You, as programmer, choose the compromize; it's not
forced on you by the language. For large, complex objects,
where the compile time dependencies are an issue, you use either
an abstract base class or the compilation firewall idiom. For
simple, time critical values (e.g. things like std::complex),
you declare the private members in the header, so that the
compiler can optimize their use. You have the choice; it isn't
imposed on you by the language.
 

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