Do you use const member a lot?

R

red floyd

E. Robert Tisdale said:
But even some variable objects will have members that
*should not change* once the object has been constructed.
It is important to qualify them as const
so that other programmers who must maintain your code
will get a diagnostic from the compiler
if they attempt to include code which modifies const data members.

Unless you want to use your object in a container. And then your
default initializer for your const object had BETTER be the same for
everything, since containers use the default constructor + assignment
metaphor.

If you want to use the class in a container, and you have const data
that varies based on construction method (default/copy/other
constructor), then it should be private data with only a read accessor.
 
E

E. Robert Tisdale

red said:
Unless you want to use your object in a container.
And then your default initializer for your const object
had BETTER be the same for everything,
since containers use the default constructor + assignment metaphor.

If you want to use the class in a container,
and you have const data that varies based on construction method
(default/copy/other constructor),
then it should be private data with only a read accessor.

You could be correct. It's hard to tell from what you wrote.
Maybe an example
Code:
 would help.
 
J

JKop

E. Robert Tisdale posted:

A const variable is an oxymoron.
An object is either a constant or a variable -- not both.


I disagree:


void Nokia(const int* jam)
{
jam += 5;
}


int main(void)
{
const int carnage = 7;

Nokia(&carnage);
}


Although a dictionary may tell you that the noun, "variable", is defined as
a thing that varies, and that the noun, "constant", refers to a thing that
under-goes no change whatsoever; these are spoken language definitions.
In the above, I've gotten the address of a variable, a const variable.


That's my 2 cents.


-JKop
 
E

E. Robert Tisdale

JKop said:
E. Robert Tisdale posted:
A const variable is an oxymoron.
An object is either a constant or a variable -- not both.

I disagree:

void Nokia(const int* jam) {
jam += 5;
}


int main(int argc, char* argv[]) {
const int carnage = 7;
Nokia(&carnage); return 0;
}

Although a dictionary may tell you that
the noun, "variable", is defined as a thing that varies,
and that the noun, "constant", refers to a thing
that under-goes no change whatsoever;
these are spoken language definitions.

In the above, I've gotten the address of a variable, a const variable.

You twit.
You got the address of a constant and you added 5 to that address.
The object [carnage] to which jam points remains constant.

If you had meant to change carnage, you might have written
cat nokia.c
void Nokia(const int* jam) {
*jam += 5;
}

int main(int argc, char* argv[]) {
const int carnage = 7;
Nokia(&carnage);
return 0;
}
gcc -Wall -std=c99 -pedantic -o nokia nokia.c
nokia.c: In function `Nokia':
nokia.c:2: error: assignment of read-only location
 
R

red floyd

E. Robert Tisdale said:
red said:
Unless you want to use your object in a container.
And then your default initializer for your const object
had BETTER be the same for everything,
since containers use the default constructor + assignment metaphor.

If you want to use the class in a container,
and you have const data that varies based on construction method
(default/copy/other constructor),
then it should be private data with only a read accessor.


You could be correct. It's hard to tell from what you wrote.
Maybe an example
Code:
 would help.[/QUOTE]

quick and dirty (not tested)

class A {
private:
const int x;
public:
A() : x(0) { }
A(const A& a) : x(a.x) { }
A(const char *p) : x(2) { }
A& operator=(const A&); // how do we implement this
// to get correct semantics?
int get_x() const { return x; }
};

The question is, how do we implement A::operator=(const A&) to get
proper container semantics where elements of a container are usually
default constructed followed by assignment?
 
R

ralpe

So, this is to justify the use of const with reference semantics,
which is still consistent with my original observation: value
semantics kills it.

I won't argue about whether value semantics is wanted more often or
less often than reference semantics.

When designing classes, I'm quite reluctant in teaching my users: "you
should use it in this way, not the other way", unless that can
dramatically ease my programming or simplify the architecture.
Unfortunately, const member is never found justifiable with this
criteria.


My intention is to make my class as orthogonal to the language as
possible. that is, users choose how they want to use it, I just define
what my class does and what it requires. If users can use "int" in
certain way, I hope they can use my class the same way as they prefer.

Just because value semantics is the default in C++ does not mean that
everything should be a value. That's why C++ has references too. You
just need both value and reference semantics. In Java, where reference
semantics is the default, values are designed as immutable objects.
i.e., they should be able to choose where to store this object, in
stack, in heap, embedded in another object, used with smart pointer,
scope guard, blah blah blah, any way they like.
Why?

I consider that flexibility very important.

Why?
 
J

JKop

E. Robert Tisdale posted:
JKop said:
E. Robert Tisdale posted:
A const variable is an oxymoron.
An object is either a constant or a variable -- not both.

I disagree:

void Nokia(const int* jam) {
jam += 5;
}


int main(int argc, char* argv[]) {
const int carnage = 7; Nokia(&carnage); return 0; }

Although a dictionary may tell you that
the noun, "variable", is defined as a thing that varies, and that the
noun, "constant", refers to a thing that under-goes no change
whatsoever; these are spoken language definitions.

In the above, I've gotten the address of a variable, a const variable.

You twit.
You got the address of a constant and you added 5 to that address.
The object [carnage] to which jam points remains constant.

Exactly... now you're learning!

If you had meant to change carnage, you might have written

Hypothectically speaking, yes, if I'd made a change to carnage, I would have
written... but that's irrelevant.

If you're brain can't handle it, just replace "jam += 5" with ";".
cat nokia.c
void Nokia(const int* jam) {
*jam += 5;
}

int main(int argc, char* argv[]) {
const int carnage = 7;
Nokia(&carnage);
return 0;
}
gcc -Wall -std=c99 -pedantic -o nokia nokia.c
nokia.c: In function `Nokia':
nokia.c:2: error: assignment of read-only location
 
B

Ben

Just because value semantics is the default in C++ does not mean that
everything should be a value. That's why C++ has references too. You
just need both value and reference semantics. In Java, where reference
semantics is the default, values are designed as immutable objects.

Java has no value semantics except primitive types. Immutable objects
use reference semantics too. That's why you can embed immutable object
_reference_ in an array or another object. And that's why users can
choose to make their BankAccount attribute mutable even though
BankAccount is immutable.

class BankAccount{
private final String number;
...
}
class MyClass{
private BankAccount acc;
public void setBankAccount(BankAccount a){this.acc = c;}
}

I see that as a nice separation of designer's concern and user's
concern.



While in value semantics, you don't have this natural separation. And
then you have to decide whose concern is more important, yours or the
user's.


I personally feel bad if I have to force my users not to do certain
legitmate things. (such as storing my object _inline_ in a vector).
If I can't find strong reason for doing that ('strong' meaning no
alternative with the same level of complexity), I'd stay silent about
my users' business.
 
N

Niklas Borson

E. Robert Tisdale said:
A const variable is an oxymoron.
An object is either a constant or a variable -- not both.

The phrase "const variable" sounds like an oxymoron if you think of
const as meaning "cannot change" and variable as meaning "can change";
but these are insufficiently precise definitions borrowed from casual,
every-day English. If we're talking about C++ we should use these
terms as they are defined in the C++ standard.

In C++, the term variable does not mean non-const. A variable is simply
a name that denotes an object. (From 3. Basic Concepts, "A variable is
introduced by the declaration of an object. The variable's name denotes
the object.") Thus, in the following example, k is a variable which
also happens to be const:

const int k = 0;

Perhaps you would argue that k is not really an object. If so, you'd
be wrong. The compiler may replace occurrences of k in expressions
with 0, and might even optimize away the memory allocated to k, but
these are optimizations; k is still an object according to the rules
of the language; if it weren't you wouldn't be able to take its
address (perhaps this is the point JKop was trying to make).

So QED. But arguments by reference to the standard are not always
very satisfying (convincing yes, but not always satisfying) so
I'll try to give a more intuitive explanation.

Let's make a little detour into mathematics. Consider the equation:

f(x) = x^2 + x + 1

Here we've defined f as a function of x, where x is a variable.
By variable, we mean only that we don't know the value of x in
advance; but once we "plug in" a value for x, we don't expect it
to change from one occurrence to the next.

Now let's consider a similar C++ function:

double f(const double x)
{
return (x * x) + x + 1;
}

Here x is a variable in the C++ sense (a name bound to an object)
and also in the mathematical sense (an unknown value). It is also
const, which means we can expect every occurrence of x to have the
same value -- just as in the mathematical expression.

Now it's true (AFAIK - I'm no mathematician) that in math a symbol
is either a variable or a constant, not both. But "const" in C++
does not mean something is constant in the sense of a fixed, known
value like e or pi; it means something closer to "read-only".

A nearer equivalent to a mathematical constant would be k from the
first example above. In C++, k is a variable which also happens to
be an "integral constant expression" (per 5.19 because it is a const
int variable initialized using an integral constant expression; note
here that "constant" and "const" are NOT synonyms). This is a bit of
a departure from math. But really, it's an arbitrary choice whether
to think of constants and variables as mutually exclusive categories;
or of constants as a sort of special, degenerate case of variables.
C++ takes the latter approach. An advantage is that you can use k
anywhere you would use a variable of the same type, and you don't
need a whole separate set of language rules to do so.
 
R

Richard Herring

ralpe said:
(e-mail address removed) (Ben) wrote in message


Why would you want two BankAccount objects with the same account number (id)?

Exception safety and commit/rollback semantics?
 
J

JKop

Niklas Borson posted:

const int k = 0;

Perhaps you would argue that k is not really an object. If so, you'd
be wrong. The compiler may replace occurrences of k in expressions
with 0, and might even optimize away the memory allocated to k, but
these are optimizations; k is still an object according to the rules
of the language; if it weren't you wouldn't be able to take its
address (perhaps this is the point JKop was trying to make).

Exactly the point I was trying to make.
Now it's true (AFAIK - I'm no mathematician) that in math a symbol
is either a variable or a constant, not both. But "const" in C++
does not mean something is constant in the sense of a fixed, known
value like e or pi; it means something closer to "read-only".

I myself prefer the term "read-only". I hear that once back in the way old
days of C, they called it "readonly" as opposed to "const", or something
along those lines.

Anyway, when I hear some-one say "a const", I think:

#define monkey 5


as opposed to:

unsigned char const monkey = 5;



-JKop
 
N

Niklas Borson

JKop said:
Anyway, when I hear some-one say "a const", I think:

#define monkey 5


as opposed to:

unsigned char const monkey = 5;

I would probably refer to either version as "a constant", since the
intent is the same in both cases. However, I'd prefer the latter
version because it doesn't conflict with other possible code like

class Primate {
...
enum Species {
monkey,
ape
};
};

or

namespace idle {
void fiddle();
void twiddle();
void monkey();
};
 

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,170
Messages
2,570,925
Members
47,468
Latest member
Fannie44U3

Latest Threads

Top