Thursday, February 11, 2016

Digest for comp.lang.c++@googlegroups.com - 25 updates in 6 topics

JiiPee <no@notvalid.com>: Feb 11 04:19PM

I have always used getters/setters but now I read about them being
"evil": http://www.yegor256.com/2014/09/16/getters-and-setters-are-evil.html
 
Lets have an example:
 
class PersonDetails
{
private:
string name;
int age;
};
 
Now, how would you get access to name and age without getters and
setters? Lets say we have new information about the persons name.... its
now "John Smith", was "John".
So how to change that name without a setter?
"K. Frank" <kfrank29.c@gmail.com>: Feb 11 09:15AM -0800

Hi JiiPee!
 
On Thursday, February 11, 2016 at 11:20:11 AM UTC-5, JiiPee wrote:
> setters? Lets say we have new information about the persons name.... its
> now "John Smith", was "John".
> So how to change that name without a setter?
 
I, very frequently, just access the data members directly.
Of course, they have to be public to do this:
 
class PersonDetails
{
public:
string name;
int age;
};
 
or
 
struct PersonDetails
{
string name;
int age;
};
 
Then just access them:
 
PersonDetails pd;
pd.name = "John Smith";
 
The simpler the class, the less it has class invariants,
and the more POD-ish (plain old data) it is, the more likely
I am to make data members public, and access them directly.
 
(Stylistically, I often use "struct" instead of "class" for
classes that are "morally" POD, as well as for true POD classes.)
 
Having said that, I don't think that getters/setters are
evil -- they're just something of a nuisance, especially
in simple settings.
 
 
Best.
 
 
K. Frank
Paavo Helde <myfirstname@osa.pri.ee>: Feb 11 08:05PM +0200

On 11.02.2016 18:19, JiiPee wrote:
> setters? Lets say we have new information about the persons name.... its
> now "John Smith", was "John".
> So how to change that name without a setter?
 
If you read a bit past the headline of your link, then you see that he
does not advocate removing the setters, but renaming them:
 
person.TakeNewName("John Smith");
 
person.LiveAndSuffer(Years(30));
 
Not sure if this is useful for anything.
scott@slp53.sl.home (Scott Lurndal): Feb 11 06:20PM

>setters? Lets say we have new information about the persons name.... its
>now "John Smith", was "John".
>So how to change that name without a setter?
 
Create a new instance of the object and destroy the original. e.g. have
a constructor that takes a reference to the orignal and the updated
name.
 
PersonalDetails(PersonalDetails& orig, string newname)
{
name = newname;
age = orig.age;
}
Wouter van Ooijen <wouter@voti.nl>: Feb 11 08:09PM +0100

Op 11-Feb-16 om 5:19 PM schreef JiiPee:
> setters? Lets say we have new information about the persons name.... its
> now "John Smith", was "John".
> So how to change that name without a setter?
 
First, think if it realy makes sense to change the name of the person.
Did he/she realy apply for a name change and got permission? And instead
of age, why not store the date of birth (which is not likely to change)?
 
Next, pure getters and setters make sense when there is a significant
chance that at some moment in the life cycle of your software, you will
change the private data without a change in the interface. If you need
to do this, you will be very gratefull for the abstraction of the
getter/setters.
 
If the chance that you will do that is (almost) zero, getters/setters
are a nuisance, and you should instead make the attributes public.
 
Non-pure getters/setters (that do something more than just
setting/getting the attribute) are of course a different story.
 
Wouter van Ooijen
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 11 08:41PM +0100

On 2/11/2016 8:09 PM, Wouter van Ooijen wrote:
> getter/setters.
 
> If the chance that you will do that is (almost) zero, getters/setters
> are a nuisance, and you should instead make the attributes public.
 
Requirements can change.
 
And they do.
 
Bertrand Meyer thought that this was important enough to make member
function invocations look like data attribute access in Eiffel, so that
a data attribute could be replaced with a member function or vice versa
without affecting client source code. He called this the [1]"uniform
access principle". I his words, in his 1988 book [2]"Object Oriented
Software Construction" (which really was a combined introduction to and
rationale of Eiffel, sort of like a combination of Bjarne's TCPPL and
Design & Evolution books): "All services offered by a module should be
available through a uniform notation, which does not betray whether they
are implemented through storage or through computation".
 
In C++ one can implement uniform access by implementing read only
properties, but this has both a memory cost (back-pointer to the object
in each such attribute) and an execution cost (extra indirection).
 
I think the uniform access principle is the least weak argument for C++
language support for properties. But ideally, when a direct data
attribute is replaced with a read-only property function, that function
should be a /pure function/, possibly except caching of results, to
avoid the property-with-side-effects nightmare of e.g. properties in C#.
And the only guaranteed pure functions in current C++ are `constexpr`
functions, which is too restrictive to be useful for this.
 
 
> Non-pure getters/setters (that do something more than just
> setting/getting the attribute) are of course a different story.
 
Yes.
 
 
Cheers,
 
- Alf
 
Notes:
[1] <url: https://en.wikipedia.org/wiki/Uniform_access_principle>
[2] <url:
https://en.wikipedia.org/wiki/Object-Oriented_Software_Construction>
Wouter van Ooijen <wouter@voti.nl>: Feb 11 08:51PM +0100

Op 11-Feb-16 om 8:41 PM schreef Alf P. Steinbach:
 
>> If the chance that you will do that is (almost) zero, getters/setters
>> are a nuisance, and you should instead make the attributes public.
 
> Requirements can change.
 
That's why my statement doesn'te even mention the (current)
requirements. I ask for a judgement call about the future.
Getters/setters are a nuisance, but a very small one compared to the
updating of a large amount of client code.
 
But there are some cases in which IMO public attributes are the bettre
choice, for instance locations (x,y coordinate pairs) on a small
(embedded) LCD screen. No chnace in hell that I will ever replace them
with an angle/distance pair. But as said, when in doubt favour
getters/setters.
 
Wouter van Ooijen
JiiPee <no@notvalid.com>: Feb 11 07:56PM

On 11/02/2016 18:20, Scott Lurndal wrote:
> name = newname;
> age = orig.age;
> }
 
ok, this has a point.... have to think about....
So instead of setter, we would always pass the object and the new value.
JiiPee <no@notvalid.com>: Feb 11 07:58PM

On 11/02/2016 19:09, Wouter van Ooijen wrote:
>> So how to change that name without a setter?
 
> If the chance that you will do that is (almost) zero, getters/setters
> are a nuisance, and you should instead make the attributes public.
 
Sutter argues strongly that you should always use functions to get
access to data members....
woodbrian77@gmail.com: Feb 10 03:34PM -0800

On Tuesday, February 9, 2016 at 5:24:28 PM UTC-6, Richard wrote:
 
 
http://www.wikihow.com/Stop-Swearing
 
 
Brian
Ebenezer Enterprises
http://webEbenezer.net
Ian Collins <ian-news@hotmail.com>: Feb 11 03:10PM +1300

> On Tuesday, February 9, 2016 at 5:24:28 PM UTC-6, Richard wrote:
 
Please stop posting bollocks.
 
--
Ian Collins
legalize+jeeves@mail.xmission.com (Richard): Feb 11 06:50PM

[Please do not mail me a copy of your followup]
 
Ian Collins <ian-news@hotmail.com> spake the secret code
 
>woodbrian77@gmail.com wrote:
>> On Tuesday, February 9, 2016 at 5:24:28 PM UTC-6, Richard wrote:
 
>Please stop posting bollocks.
 
I didn't know what you were talking about until I found the shitty
post by woodbraindead77. I knew there was a reason I found room for
that address in my KILL file.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
Gareth Owen <gwowen@gmail.com>: Feb 11 07:54PM


> On Tuesday, February 9, 2016 at 5:24:28 PM UTC-6, Richard wrote:
 
> http://www.wikihow.com/Stop-Swearing
 
http://www.wikihow.com/Stop-Imposing-Your-Bizarre-Moral-Compass-On-Others
"K. Frank" <kfrank29.c@gmail.com>: Feb 11 09:18AM -0800

I am playing around with the CRTP (curiously recurring
template pattern) to get a feel for when it might be
useful in practice.
 
Does my simple example below show the full structure
of the CRTP, or am I missing an important part of the
picture?
 
(As I understand it, you can use the CRTP instead of a
similar virtual-function design, avoiding the virtual-
function overhead at the cost of giving up run-time
polymorphism.)
 
My simple example uses the CRTP for reuse and customization
of code. The idea is that Base::doStuff() implements
non-trivial logic (trivial in the example) that CRTP-derived
classes can reuse and customize by overriding doA(), etc.
 
template<typename D> struct Base {
void doStuff() {
static_cast<D*>(this)->doA();
static_cast<D*>(this)->doB();
static_cast<D*>(this)->doC();
}
// no default for doA
void doB() { cout << "Base::doB" << endl; } // default doB
void doC() { cout << "Base::doC" << endl; } // default doC
};
 
struct D1 : public Base<D1> {
void doA() { cout << "D1::doA" << endl; } // implement doA
void doB() { cout << "D1::doB" << endl; } // override doB
// use default doC from Base
};
 
Is this the basic structure and purpose of the CRTP?
 
 
Thanks.
 
 
K. Frank
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 11 06:56PM +0100

On 2/11/2016 6:18 PM, K. Frank wrote:
> // use default doC from Base
> };
 
> Is this the basic structure and purpose of the CRTP?
 
This structure, where a derived class can customize part of a procedure,
is called the template pattern.
 
It's one way to use CRTP.
 
In your next posting you describe another way to use CRTP, namely to
define a non-virtual interface.
 
The original use of CRTP, by Barton and Nackman in their 1994 book
"Scientific and Engineering C++" (if I recall this correctly), was to
inherit in a mixin class. E.g. I use CRTP to inherit in relational
operators defined in terms of the derived class' `compare` function.
This relied on a subtle rule, called "friend name injection", that have
since been removed because the Baron-Nackman trick was its only use;
instead a friend function defined inline in a class is now found via
argument dependent lookup, so that the trick still works.
 
Summing up, the CRTP technique is a basic tool that can be used for many
different things.
 
Some people think that using CRTP for compile time polyorphism will
always result in code bloat, the compiler generating umpteen slightly
different machine code pieces for the same little source snippet. And so
it was in early pre-standard C++. But when I measured this around the
year 2000 somewhere, for at least some simple small programs the
run-time polymorphism yielded less code than using virtual functions.
 
 
Cheers & hth.,
 
- Alf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 11 07:00PM +0100

On 2/11/2016 6:56 PM, Alf P. Steinbach wrote:
> it was in early pre-standard C++. But when I measured this around the
> year 2000 somewhere, for at least some simple small programs the
> run-time polymorphism yielded less code than using virtual functions.
^^^^^^^^
 
"compile time"
 
Also, "has" instead of "have" somewhere earlier.
 
Why don't Usenet clients offer a preview, with such errors indicated,
when one clicks the "Send" button?
 
 
Just wondering,
 
- Alf
Paavo Helde <myfirstname@osa.pri.ee>: Feb 11 08:21PM +0200

On 11.02.2016 20:00, Alf P. Steinbach wrote:
 
> "compile time"
 
> Why don't Usenet clients offer a preview, with such errors indicated,
> when one clicks the "Send" button?
 
If the usenet client is smart enough to know what is correct, "compile
time" or "run time", then I suspect it won't need your help any more and
can answer the posts by itself ;-)
"K. Frank" <kfrank29.c@gmail.com>: Feb 11 11:39AM -0800

Hi Alf!
 
On Thursday, February 11, 2016 at 12:56:37 PM UTC-5, Alf P. Steinbach wrote:
> "Scientific and Engineering C++" (if I recall this correctly), was to
> inherit in a mixin class. E.g. I use CRTP to inherit in relational
> operators defined in terms of the derived class' `compare` function.
 
I've read through the Barton and Nackman CRTP (as described by
Coplien). Would you describe it as fundamentally structurally
different than my example, or is it used for a conceptually
different purpose, but is structurally the same?
 
I would draw the parallel as follows:
 
operator= (in the CRTP base class) implements the "non-trivial"
logic of defining "equals" in terms of "less than." The derived
class "customizes" this behavior by implementing operator<.
 
Is there more to the Barton-Nackman machinery than meets my eye?
 
> since been removed because the Barton-Nackman trick was its only use;
> instead a friend function defined inline in a class is now found via
> argument dependent lookup, so that the trick still works.
 
I assume that "friend name injection" and ADL come into play
because we're defining operators (where ADL is most useful),
but, other than this syntactic issue, we're just working with
otherwise regular member and/or friend functions. Or am I missing
something important about the Barton-Nackman structure.?
 
> ...
 
> Cheers & hth.,
 
> - Alf
 
 
Thanks.
 
 
K. Frank
red floyd <no.spam@its.invalid>: Feb 11 10:41AM -0800

On 2/10/2016 11:04 AM, Ian Collins wrote:
 
>>> Maybe his concern was the word "crap" - which is not really swearing
 
>> I don't think "crap" is swearing.
 
> So what did you object to?
 
Who gives a shit?
"K. Frank" <kfrank29.c@gmail.com>: Feb 11 09:28AM -0800

Hello Group!
 
To follow up on my previous post, I have also seen
discussions where the CRTP (curiously recurring
template pattern) is used, as I understand it, to
define interfaces.
 
I suppose that this usage goes something like this:
 
template<typename D> struct Interface {
void doA() { static_cast<D*>(this)->implementationA(); }
void doB() { static_cast<D*>(this)->implementationB(); }
void doC() { static_cast<D*>(this)->implementationC(); }
};
 
Then a class that implements the interface could be:
 
struct D1 : public Interface<D1> {
void implementationA() { cout << "D1::implementationA" << endl; }
void implementationB() { cout << "D1::implementationB" << endl; }
void implementationC() { cout << "D1::implementationC" << endl; }
};
 
and could be used as follows:
 
template<typename T> struct UseInterface {
void doStuff() {
T t;
t.doA();
t.doB();
t.doC();
}
};
 
UseInterface<D1> ud;
ud.doStuff;
 
It's true that the class Interface serves to define the
interface to be implemented, but having to manually map
the interface to the implementation:
 
void doA() { static_cast<D*>(this)->implementationA(); }
 
seems annoying.
 
My preference in a case like this would be to just define
a class that "duck-types" the desired interface:
 
struct C {
void doA() { cout << "C::doA" << endl; }
void doB() { cout << "C::doB" << endl; }
void doC() { cout << "C::doC" << endl; }
};
 
and use it, e.g.:
 
UseInterface<C> uc;
uc.doStuff;
 
Am I missing anything about the benefits of using the
CRTP to define interfaces? If not, do you think that
using the CRTP as a place to define an interface is
worth the hassle?
 
 
Thanks.
 
 
K. Frank
Alex Vinokur <alex.vinokur@gmail.com>: Feb 11 01:11AM -0800

It seems that output of fmod (long double, long double) in this test is problematocs.
Any suggestions?
 
See below.
 
 
> g++ --version
g++ (GCC) 4.9.2
 
> uname -srvmpio
CYGWIN_NT-6.1 1.7.34(0.285/5/3) 2015-02-04 12:12 i686 unknown unknown Cygwin
 
 
> g++ test1.cpp
// No errors, no warnings
 
 
> ./a.exe
 
l1 = 4294967296
l2 = 72057594037927934
l3 = 4294967294
 
d1 = 4294967296
d2 = 72057594037927934
d3 = 0 // Expected 4294967294
 
 
// -------- Program test1. cpp --------
#include <iostream>
#include <iomanip>
#include <cmath>
 
int main (int argc, char** argv)
{

long long l1 = 4294967296;
long long l2 = 72057594037927934;
long long l3 = l2 % l1;
 
long double d1 = static_cast<long double>(l1);
long double d2 = static_cast<long double>(l2);
long double d3 = fmod (d2, d1);
 
std::cout << "l1 = " << l1 << std::endl;
std::cout << "l2 = " << l2 << std::endl;
std::cout << "l3 = " << l3 << std::endl;
 
std::cout << std::endl;
std::cout << "d1 = " << std::setprecision(18) << d1 << std::endl;
std::cout << "d2 = " << std::setprecision(18) << d2 << std::endl;
std::cout << "d3 = " << std::setprecision(18) << d3 << std::endl;
 
return 0;
 
}
// -----------------------
Paavo Helde <myfirstname@osa.pri.ee>: Feb 11 12:25PM +0200

On 11.02.2016 11:11, Alex Vinokur wrote:
 
> return 0;
 
> }
> // -----------------------
 
The root problem is that d3 gets rounded to a double at some point,
becoming 72057594037927936. With MSVC this happens already at d2
definition because in MSVC long double is the same as double. But with
gcc it should work in principle as long double has more precision there.
 
Anyway, it seems there are two problems:
 
1. <cmath> defines fmod() overloads in std:: namespace, so you need to
use std::fmod, not fmod. The latter (at least with gcc) only finds the C
version fmod(double, double). The std::fmod() works correctly with g++
4.6.2 on Linux, for example.
 
2. Even if you use std::fmod(), it seems that Cygwin g++ has not
implemented the long double version (it is lacking fmodl() as well), so
it is still falling back to the double version.
jacobnavia <jacob@jacob.remcomp.fr>: Feb 11 11:30AM +0100

CYGWIN uses as its run time the CRTDLL.DLL software of Microsoft. Since
Microsoft does NOT implement long double, nothing that uses long double
will work under cygwin.
 
The compiler (gcc) does not know this and supposes that long double is
different than double.
 
Since printf/fmodl, etc do not work, there are since years always this
kinds of questions. Apparently the docs do not tell this very clearly.
 
DO NOT USE LONG DOUBLE WHEN USING CYGWIN!
Alex Vinokur <alex.vinokur@gmail.com>: Feb 11 02:39AM -0800

On Thursday, February 11, 2016 at 11:12:28 AM UTC+2, Alex Vinokur wrote:
Alex Vinokur <alex.vinokur@gmail.com>: Feb 11 02:40AM -0800

On Thursday, February 11, 2016 at 12:25:45 PM UTC+2, Paavo Helde wrote:
 
> 2. Even if you use std::fmod(), it seems that Cygwin g++ has not
> implemented the long double version (it is lacking fmodl() as well), so
> it is still falling back to the double version.
 
Thanks.
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: