220 7557 <5eeafd6f-32f3-4281-9374-617af852fe21@isocpp.org> article
Path: news.gmane.org!not-for-mail
From: mitchnull@gmail.com
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Fixing the private method issue
Date: Sun, 3 Nov 2013 09:10:17 -0800 (PST)
Lines: 211
Approved: news@gmane.org
Message-ID: <5eeafd6f-32f3-4281-9374-617af852fe21@isocpp.org>
References: <d5cd9fa5-ac2f-465b-b92d-cf2a35607245@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; 
	boundary="----=_Part_2149_29710459.1383498617420"
X-Trace: ger.gmane.org 1383498615 20173 80.91.229.3 (3 Nov 2013 17:10:15 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Sun, 3 Nov 2013 17:10:15 +0000 (UTC)
Cc: fmatthew5876@gmail.com
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBC36XNFZ4YKBB6UG3KJQKGQEFHDIDMA@isocpp.org Sun Nov 03 18:10:21 2013
Return-path: <std-proposals+bncBC36XNFZ4YKBB6UG3KJQKGQEFHDIDMA@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-ob0-f197.google.com ([209.85.214.197])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBC36XNFZ4YKBB6UG3KJQKGQEFHDIDMA@isocpp.org>)
	id 1Vd1Bs-0006Np-A2
	for gclcip-std-proposals@m.gmane.org; Sun, 03 Nov 2013 18:10:20 +0100
Original-Received: by mail-ob0-f197.google.com with SMTP id vb8sf20267935obc.0
        for <gclcip-std-proposals@m.gmane.org>; Sun, 03 Nov 2013 09:10:19 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20120113;
        h=date:from:to:cc:message-id:in-reply-to:references:subject
         :mime-version:x-original-sender:reply-to:precedence:mailing-list
         :list-id:list-post:list-help:list-archive:list-subscribe
         :list-unsubscribe:content-type;
        bh=1AoQdsdg/DIOmM1HWzz6LDJtw+g27/ixKTCZrgp0/4M=;
        b=KnZqA7QyMdRzRkVZOYamPNF8nxqoLiMPRd+4l2VyaBuYWVuVMZpE5mCOXokwTq6hH5
         cy4YhYfziAB9yYWe75+XHNXAILuuqGWJInC9Cqn9hprJUFQSo2S1hM4dHvvKqb/B5JcJ
         qF1ZTJ3SXzFo3OmzzicOgVWanlfQ5XteXRZajGg+1an/bAvKPfU/wEX7UeVpXvqehEv4
         Q7pxHCM88GtgQWwviHkvpGWKFOJXiPFCoQ224dJQ9YBCSWIuNYZdZh7yTTv7uAl5Irht
         0KnmvK1vPIeRu5rI6qN/KtpjmI32EZ2Z+UOxkBgGQB+8gADlC6PwxBEBnonF9FWAQrmb
         kYkQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:date:from:to:cc:message-id:in-reply-to
         :references:subject:mime-version:x-original-sender:reply-to
         :precedence:mailing-list:list-id:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe:content-type;
        bh=1AoQdsdg/DIOmM1HWzz6LDJtw+g27/ixKTCZrgp0/4M=;
        b=ZJvm3YUm6JWeqv92d9dzkaybD7Ucy3hGnrdZqWCH6LIUubd5R+LIXnARg0AiWXRglR
         pkThhdYWyn0RSL11RzVlJ+/V2FKd92ceAXwGmkb216i7s/1tCX+0MDukXxlEYkvxS3Ox
         89vxos7c7iOP+dK/giJfYWGQrNDGjc0zFVxGZFnRgXAbfJRQKPPcO1HfylIfirAia8dw
         gfoXBG0/DV2wKPRvu59UgF2PeUh17x9JijDsyKEat1iI2+6kmmitBmFHf0LfW0PThKif
         fuhVeqZ5FhO0xyVkA3+uqPH7k6tG/YhDN6SIHK+gt/5VO9t0UzrgbN1EIxA1OJNp6Oxz
         GwwA==
X-Gm-Message-State: ALoCoQn1AwUo1zXUtHK68K0OtOAruXq3LSxmDq4CxWs1ce7QZyXH5jMAZ3A/DI73wtNludSyXrPg
X-Received: by 10.182.245.197 with SMTP id xq5mr3630717obc.27.1383498618976;
        Sun, 03 Nov 2013 09:10:18 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.49.129.65 with SMTP id nu1ls2023552qeb.31.gmail; Sun, 03 Nov
 2013 09:10:17 -0800 (PST)
X-Received: by 10.49.12.100 with SMTP id x4mr333887qeb.0.1383498617970;
        Sun, 03 Nov 2013 09:10:17 -0800 (PST)
In-Reply-To: <d5cd9fa5-ac2f-465b-b92d-cf2a35607245@isocpp.org>
X-Original-Sender: mitchnull@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <http://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <http://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <http://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:7557
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/7557>

------=_Part_2149_29710459.1383498617420
Content-Type: text/plain; charset=ISO-8859-1

Hello,

   I've been thinking about a new proposal for a "class implementation 
namespace", where I initially thought to only allow member function 
implementations that were already declared, but reading this proposal I 
realized that allowing new private member function declarations would solve 
your problem. It would look something like this using your example:

//foo.hh

class Foo {
  public:
    void doWork();
  private:
    int _f;
}

//foo.cc:

class Foo namespace {

// optional forward declaraction:
  void doWrokHelper();  // implicitly private

// definition of doWorkHelper() private member function declared above:
  void doWorkHelper() {
     doSomethingWith(_f);
  }
  
// definition of doWork() public member function declared in Foo.hh:
  void doWork() {
     doWorkHelper();
  }
} // end class Foo namespace (the "implementation namespace")

In my opinion this "class implementation namespace" would be a cleaner 
solution to your issue, and would also have additional benefits:
  - template class member function implementations could be separated from 
the main class declaration without having to resort to ugly repetitions
  - member functions returning nested classes could be written the same way 
as declared (this is a common problem for new learners according to my 
experience)
  - in general, the "implementation" part would be syntactically similar to 
the declaration part, without unnecessary repetition of the class name, etc

I'll try to write a detailed proposal next week (I first wanted to 
implement this concept in clang, but I guess it's better to get out the 
idea first...)

cheers,
mitch

On Wednesday, October 30, 2013 4:39:17 AM UTC+1, fmatth...@gmail.com wrote:
>
> There is one major wart in C++ class design, and that is with private 
> member functions required to be in the class definition.
>
> This has a number of problems:
> 1) Changing the private method's signature or adding/removing private 
> methods requires everyone including the header to recompile. This is a huge 
> problem for large projects with long recompilation times.
> 2) file static / anonymous namespace definitions in the .cc file cannot be 
> used in the private method's signature. Anything used in the signature must 
> be at least forward declared in the header, adding more symbol pollution.
> 3) For shared library interfaces, the private methods are extra 
> unnecessary symbols that have to be managed.
> 4) Private method signatures or even the existence of private methods can 
> depend on the underlying implementation. If the class has multiple 
> implementations (e.g. different platforms), #defines and other conditional 
> compilation mechanisms are required in the header file.
> 5) Its just bad encapsulation. Callers don't need to know anything about 
> the functions which implement the class behavior.
>
> The only private declarations that should be required in the header are 
> declarations required by the compiler. I believe all of those are:
> 1) Private data members (sizeof())
> 2) Private virtual methods (for inheriting)
> 3) Private non-virtual methods called by inline functions.
>
> One way to do this would be to extend the friend feature. We could define 
> friend functions within the body of member functions. It might look like 
> this:
>
> //foo.hh
>
> class Foo {
>   public:
>     void doWork();
>   private:
>     int _f;
> }
>
> //foo.cc
> static void doWorkHelper(Foo* f) {
>   doSomethingWith(f->_f);
> };
>
> void Foo::doWork() {
>   friend void doWorkHelper(Foo*);
>
>   doWorkHelper(this);
> }
>
> This has potential for abuse of course, but it would finally allow us to 
> limit the list of declarations in the class definition to the bare minimum 
> required by the compiler. When it comes to defining interfaces, less is 
> always more.
> One other use of this feature could be to add a backdoor for unit tests.
>
> Thoughts?
>

-- 

--- 
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_2149_29710459.1383498617420
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hello,<div><br></div><div>&nbsp; &nbsp;I've been thinking =
about a new proposal for a "class implementation namespace", where I initia=
lly thought to only allow member function implementations that were already=
 declared, but reading this proposal I realized that allowing new private m=
ember function declarations would solve your problem. It would look somethi=
ng like this using your example:</div><div><br></div><div><div>//foo.hh</di=
v><div><br></div><div>class Foo {<br>&nbsp; public:</div><div>&nbsp; &nbsp;=
 void doWork();</div><div>&nbsp; private:</div><div>&nbsp; &nbsp; int _f;</=
div><div>}</div><div><br></div><div>//foo.cc:</div><div><br></div><div>clas=
s Foo namespace {</div><div><br></div><div>// optional forward declaraction=
:</div><div>&nbsp; void doWrokHelper(); &nbsp;// implicitly private</div><d=
iv><br></div><div>// definition of doWorkHelper() private member function d=
eclared above:</div><div>&nbsp; void doWorkHelper() {</div><div>&nbsp; &nbs=
p; &nbsp;doSomethingWith(_f);</div><div>&nbsp; }</div><div>&nbsp;&nbsp;</di=
v><div>// definition of doWork() public member function declared in Foo.hh:=
</div><div>&nbsp; void doWork() {</div><div>&nbsp; &nbsp; &nbsp;doWorkHelpe=
r();</div><div>&nbsp; }</div><div>} // end class Foo namespace (the "implem=
entation namespace")</div><div><br></div><div>In my opinion this "class imp=
lementation namespace" would be a cleaner solution to your issue, and would=
 also have additional benefits:</div></div><div>&nbsp; - template class mem=
ber function implementations could be separated from the main class declara=
tion without having to resort to ugly repetitions</div><div>&nbsp; - member=
 functions returning nested classes could be written the same way as declar=
ed (this is a common problem for new learners according to my experience)</=
div><div>&nbsp; - in general, the "implementation" part would be syntactica=
lly similar to the declaration part, without unnecessary repetition of the =
class name, etc</div><div><br></div><div>I'll try to write a detailed propo=
sal next week (I first wanted to implement this concept in clang, but I gue=
ss it's better to get out the idea first...)</div><div><br></div><div>cheer=
s,</div><div>mitch</div><div><br>On Wednesday, October 30, 2013 4:39:17 AM =
UTC+1, fmatth...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;"><div dir=3D"ltr">There is one major wart in C++ class design, and that i=
s with private member functions required to be in the class definition.<div=
><br></div><div>This has a number of problems:</div><div>1) Changing the pr=
ivate method's signature or adding/removing private methods requires everyo=
ne including the header to recompile. This is a huge problem for large proj=
ects with long recompilation times.</div><div>2) file static / anonymous na=
mespace definitions in the .cc file cannot be used in the private method's =
signature. Anything used in the signature must be at least forward declared=
 in the header, adding more symbol pollution.</div><div>3) For shared libra=
ry interfaces, the private methods are extra unnecessary symbols that have =
to be managed.</div><div>4) Private method signatures or even the existence=
 of private methods can depend on the underlying implementation. If the cla=
ss has multiple implementations (e.g. different platforms), #defines and ot=
her conditional compilation mechanisms are required in the header file.</di=
v><div>5) Its just bad encapsulation. Callers don't need to know anything a=
bout the functions which implement the class behavior.</div><div><br></div>=
<div>The only private declarations that should be required in the header ar=
e declarations required by the compiler. I believe all of those are:</div><=
div>1) Private data members (sizeof())</div><div>2) Private virtual methods=
 (for inheriting)</div><div>3) Private non-virtual methods called by inline=
 functions.</div><div><br></div><div>One way to do this would be to extend =
the friend feature. We could define friend functions within the body of mem=
ber functions. It might look like this:</div><div><br></div><div>//foo.hh</=
div><div><br></div><div>class Foo {<br>&nbsp; public:</div><div>&nbsp; &nbs=
p; void doWork();</div><div>&nbsp; private:</div><div>&nbsp; &nbsp; int _f;=
</div><div>}</div><div><br></div><div>//foo.cc</div><div>static void doWork=
Helper(Foo* f) {</div><div>&nbsp; doSomethingWith(f-&gt;_f);<br>};</div><di=
v><br></div><div>void Foo::doWork() {<br>&nbsp; friend void doWorkHelper(Fo=
o*);</div><div><br></div><div>&nbsp; doWorkHelper(this);</div><div>}</div><=
div><br></div><div>This has potential for abuse of course, but it would fin=
ally allow us to limit the list of declarations in the class definition to =
the bare minimum required by the compiler. When it comes to defining interf=
aces, less is always more.</div><div>One other use of this feature could be=
 to add a backdoor for unit tests.</div><div><br></div><div>Thoughts?</div>=
</div></blockquote></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_2149_29710459.1383498617420--

.
