[std-proposals] - Partial class: refinement 1

110 views
Skip to first unread message

daniele...@gmail.com

unread,
Feb 29, 2016, 1:21:40 PM2/29/16
to ISO C++ Standard - Future Proposals
The private part of a class must be declared in the same header file where the public part is also declared and therefore included by all the users of that class.
This means that whenever the private part of a class (a part of its implementation) is changed, as a consequence all the users of that class need to be recompiled.
Currently only two solutions exist to avoid this problem:

1) inheritance
2) patterns like handle/body (also know as Pimpl Idiom)

Both solutions requires additional memory costs, because each object would have an additional pointer. These additional memory costs could represent a severe penalty in Embedded Software.

A new "partial class" construct can avoid both the recompilation problem and these additional memory costs: for a complete description of this new proposal, see attachment.
Partial class.pdf

torto...@gmail.com

unread,
Mar 11, 2016, 12:17:40 PM3/11/16
to ISO C++ Standard - Future Proposals, daniele...@gmail.com
Hi,
  Some suggestions on how to improve this proposal and discussion:

Though it does not reference it this proposal copies the concept from C#.
See for example: http://stackoverflow.com/questions/3601901/why-use-partial-classes
I think the semantics and intent differ slightly.

Your intent seems to be to implement opaque types (or at least move in that direction).
Why wouldn't a proposal to properly support opaque types be better than this?
I believe the standard answer is that the ABI would require changes,
for example, to store the size of the object.
Does your proposal affect the ABI?

C# partial classes seem to be used to split the implementation of a class over several files.
The idea of splitting the implementation of something over several files has merit
but I believe this is mostly covered by the status quo.

In C# one key use is generating code for separate parts of the implementation.
You can of course implement the interface from one C++ header file across
multiple separate .cpp files but the interface must be shared.

One thing C++ currently lacks is extension methods. This is covered by other proposals
such as uniform call syntax:
  http://mariusbancila.ro/blog/2014/10/15/extension-methods-in-cpp/
  https://isocpp.org/blog/2016/02/a-bit-of-background-for-the-unified-call-proposal
There are other ways for example using templates to select free or member functions as appropriate.

Now back to your proposal.
A type used only by reference can be forward declared.
However, as you discuss, you cannot use forward declaration if you want to use the interface
but hide the implementation.

Aside from the pimpl idiom, the standard C++ way of doing this would be to have an
abstract base class defining the interface and having your client code
depend on that rather than upon a specific implementation.
i.e. polymorphic types as you mention.
I believe most modern C++ compilers are able to elide the vtable pointer
completely even virtual functions are used. If you don't declare any functions
as virtual then this problem should not exist at all.
But to do this you do need to recompile. So this is a compilation performance issue.

You say this proposal doesn't interfere with others but modules potentially offer a way of
significantly improving compile times. Would speeding up compilation with partial classes
still be worthwhile in this context? Would it be worth solving this problem
before modules or after modules or trying to integrate it with the modules TS? and why?

In one place you suggest that your proposal actually just introduces a way
of declaring forward declarations more than just the type name.
Why not a proposal for forward declaring class methods instead?
E.g.
class Foo;
int Foo::Bar(const someArg& snafu);

This would be more general purpose and not require a new "partial" keyword.

it might even be extended to cover free function extension methods if
a suitable syntax can ever be found. E.g.

class Foo;
int Bar(class Foo* this,const someArg& snafu);

Class would normally be illegal here, so it could be used to explicitly declare
an extension method. With uniform call syntax it might not be necessary at all.

Regards,

Bruce.

Daniele Bordes

unread,
Mar 12, 2016, 6:25:00 AM3/12/16
to torto...@gmail.com, ISO C++ Standard - Future Proposals
Hallo Bruce,

thank you very much for your detailed comments!
Yes, partial class as mere keyword was suggested by C# but with a different purpose.
I think you used the right words to interprete my proposal: it can be seen as a way to have opaque C++ types with no memory penalty, while preserving the class encapsulation.
I try to answer to some of your points:

"Does your proposal affect the ABI?"

No: in the example the compiler would use for the name mangling the identifier "Stack" (the name of the unique "internal class") as usual.


"You say this proposal doesn't interfere with others"

Right. Regarding Modules, they are an enormous change in the language and even in its "philosophy", still do NOT solve the problem addressed by my proposal, which has also the advantage to be incredibly small in comparison.


"Why not a proposal for forward declaring class methods instead?"

Because in that case the methods would need to be declared twice, once as forward and once in the class declaration, otherwise a class could be hacked by everyone. 
In my proposal methods are declared only once in the partial class.


"This would be more general purpose and not require a new "partial" keyword."

At the end of the .pdf of my proposal a syntax simplification is also suggested, where no additional keyword would be needed.


"Class would normally be illegal here, so it could be used to explicitly declare
an extension method." 

Same as for the forward declararion of class methods: to avoid the possibility of hacking a class, methods would need to be declared twice, and that would be tedious. This is what my proposal avoids since a single declaration is needed. Besides,my proposal has the advantage to allow to "pack" all the declarations in one place ("the partial class"), with a high cohesion of the interface. My proposal allows also to use the unified syntax if the user prefers it, so they are completely orthogonal.

I hope I clarified all the doubts!
Best regards,
Daniele
Reply all
Reply to author
Forward
0 new messages