473,395 Members | 1,578 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Do you use const member a lot?

Ben
For many times, I've found myself changing my member variables from
const back to non-const. No matter how good the original objective
was, there was always at least one reason not to use const members.
(swap, storing it in a container, etc.)
Whereas in Java, 80% of the case, I would want "final" for my instance
variables.

It makes me think that is "const member variable" ever useful in C++?

Maybe because of the value semantics of C++ objects, immutable
programming is just not good for C++.

static const is useful, const methods are useful, const parameters are
useful, const T* is useful, but just cannot find niches for const
member variables.

So, what would you use const instance member variable for? Do you use
it at all?
Jul 22 '05 #1
31 2376
Ben wrote:
For many times, I've found myself changing my member variables from
const back to non-const. No matter how good the original objective
was, there was always at least one reason not to use const members.
(swap, storing it in a container, etc.)
Whereas in Java, 80% of the case, I would want "final" for my instance
variables.

It makes me think that is "const member variable" ever useful in C++?


You have discovered that refactoring and re-featurizing are good.

Program designs are never immutable. Aspects like 'const' or non-virtual can
ensure that when you upgrade, you can lower the odds of breaking abilities.
Start with the weakest constructions possible - constants, references,
delegation - and only refactor towards mutables, pointers or inheritance as
you find a need.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces
Jul 22 '05 #2

"Ben" <be****@combined.com> wrote in message
news:24**************************@posting.google.c om...
For many times, I've found myself changing my member variables from
const back to non-const. No matter how good the original objective
was, there was always at least one reason not to use const members.
(swap, storing it in a container, etc.)
Whereas in Java, 80% of the case, I would want "final" for my instance
variables.

It makes me think that is "const member variable" ever useful in C++?

Maybe because of the value semantics of C++ objects, immutable
programming is just not good for C++.

static const is useful, const methods are useful, const parameters are
useful, const T* is useful, but just cannot find niches for const
member variables.

So, what would you use const instance member variable for? Do you use
it at all?


Some very old sage advice:

When encountering a new tool, don't waste your time
going around trying to find an application for it.

Decide what you need to do, then locate the tools
best suited for that task. While looking for the
right tools, if you see some that don't fit your
task, just leave them in the box.
-Mike
Jul 22 '05 #3
> So, what would you use const instance member variable for? Do you use
it at all?


In the code I work with, I haven't seen a lot of const member variables.
I do see const methods and parameters being used a lot.

I guess there are few cases where a member variable can be initialized
in the constructor and does not need to change for the lifetime of the
object.

Sandeep
--
http://www.EventHelix.com/EventStudio
EventStudio 2.0 - System Architecture Design CASE Tool
Jul 22 '05 #4
Ben posted:
For many times, I've found myself changing my member variables from
const back to non-const. No matter how good the original objective
was, there was always at least one reason not to use const members.
(swap, storing it in a container, etc.)
Whereas in Java, 80% of the case, I would want "final" for my instance
variables.

It makes me think that is "const member variable" ever useful in C++?

Maybe because of the value semantics of C++ objects, immutable
programming is just not good for C++.

static const is useful, const methods are useful, const parameters are
useful, const T* is useful, but just cannot find niches for const
member variables.

So, what would you use const instance member variable for? Do you use
it at all?

class BankAccount
{
protected:

const unsigned long account_number;

public:

BankAccount(unsigned long in_account_number) : account_number
(in_account_number) { ; }

};


-JKop
Jul 22 '05 #5
Ben wrote:
[snip]

So, what would you use const instance member variable for? Do you use
it at all?

I use const member variables for {named} constants
used only within the class, member function or
global function.
--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
http://www.sgi.com/tech/stl -- Standard Template Library

Jul 22 '05 #6
Ben
>
class BankAccount
{
protected:

const unsigned long account_number;

public:

BankAccount(unsigned long in_account_number) : account_number
(in_account_number) { ; }

};


-JKop


This is similar to the stuff I normally start with. It looks innocent
to have "const member" here. However, later, you will find it hard to
store in a vector or an array. Users may complain it is hard to
aggregate your BankAccount object into their own objects when they do
want to change the bankaccount attribute.
In short, this BankAccount is only good for use as a stack object,
nothing else. And very rarely you will feel satisfied with that.

Again, it is the value semantics that kills the attempt to be
immutable.

In java, even your object is immutable, users can always do functional
update to get a new value if they want. And I do like that style. But
this is not possible in C++.

So, I'd like to conclude that "immutable programming" is dead in C++
and "const member variable" is very rarely useful or just useless.
Jul 22 '05 #7
Ben posted:

class BankAccount
{
protected:

const unsigned long account_number;

public:

BankAccount(unsigned long in_account_number) : account_number
(in_account_number) { ; }

};


-JKop


This is similar to the stuff I normally start with. It looks innocent
to have "const member" here. However, later, you will find it hard to
store in a vector or an array. Users may complain it is hard to
aggregate your BankAccount object into their own objects when they do
want to change the bankaccount attribute.
In short, this BankAccount is only good for use as a stack object,
nothing else. And very rarely you will feel satisfied with that.

Again, it is the value semantics that kills the attempt to be
immutable.

In java, even your object is immutable, users can always do functional
update to get a new value if they want. And I do like that style. But
this is not possible in C++.

So, I'd like to conclude that "immutable programming" is dead in C++
and "const member variable" is very rarely useful or just useless.

I was getting at something like the following:

In a bank, the one sole piece of data by which a bank account is identified
is the account_number. After that, things like Balance and Account Holder
are just supplemental bits of data. You cannot change an account's number,
to do so would be change the one piece of data by which the account can be
identified. You would have to close the account and open a new one, which
would have a new unique number.

class BankAccount
{
protected:

const unsigned long int account_number;
char account_holder[30];

public:

BankAccount(char* in_account_holder) : account_number
(GenerateUniqueAccountNumber())
{
strcpy(in_account_holder, account_holder);
}

};
I know that my example is a bit crappy and you'd never have a class like so
or anything, but I hope it shows what I'm getting at.
-JKop
Jul 22 '05 #8
be****@combined.com (Ben) wrote in message news:<24**************************@posting.google. com>...

It makes me think that is "const member variable" ever useful in C++?


It is very useful if you tend to see objects as alogrithms (and not as
factories, trains, railroads, baboons, etc).

For example, an algorithm:

class Algorithm
{
void f1 (); // calls f2
void f2 (); // calls f1
int common_data_of_f1_and_f2;
public:
int result;
Algorithm (parameters); // calls f1 to get started
};

And that is used in a function

int foo ()
{
Algorithm A (UserTree, 123);
return A.result;
}

In such cases it makes sense to have const members for
puproses of optimization.

Best regards,

Gerald
Jul 22 '05 #9
Ben
> In a bank, the one sole piece of data by which a bank account is identified
is the account_number. After that, things like Balance and Account Holder
are just supplemental bits of data. You cannot change an account's number,
to do so would be change the one piece of data by which the account can be
identified. You would have to close the account and open a new one, which
would have a new unique number.

class BankAccount
{
protected:

const unsigned long int account_number;
char account_holder[30];

public:

BankAccount(char* in_account_holder) : account_number
(GenerateUniqueAccountNumber())
{
strcpy(in_account_holder, account_holder);
}

};


I understand that there are many business logics that require certain
field to be const or certain objects to be read-only.

The question is: is it wise to do that with "const member"? You are
sure your object will never be stored in a vector?
You are sure users never want to aggregate your object?

Yes, "this field should not change", but that can be implemented in
many ways. In c++, it is hard to say that something can never change.
Whatever the business requirement is, you may just want to be able to
change it for implementation reasons such as performance or
convenience. Say, swap.

class MyObject{
BankAccount acc;
void swap(MyObject& other){
//how do I write this if I cannot change acc?
}
};

How exactly users want to use this class should be decided by the
user. It sounds to me a too brave decision for the class designer to
say "no, I don't want it to be in a container. And no, don't aggregate
me!"

It makes more sense to say it cannot change in certain modules or
places or time, which, can be achieved by means of private/protected
and adapters.

Is it worthwhile to sacrifice flexibility for "security"? Talking
about security, with pointer arithmetics and casting present, nothing
is real secure anyway.

Well. it now sounds more something about personal flavor. One may
insist that he does not care the so-called "flexibility" and changing
one field is simply unacceptable, period. I have no disregard against
such decision.

I myself just always found I had to go back and change that decision,
however innocent it looked originally.
Jul 22 '05 #10
JKop <NU**@NULL.NULL> wrote in news:94*****************@news.indigo.ie:


I was getting at something like the following:

In a bank, the one sole piece of data by which a bank account is
identified is the account_number. After that, things like Balance and
Account Holder are just supplemental bits of data. You cannot change
an account's number, to do so would be change the one piece of data by
which the account can be identified. You would have to close the
account and open a new one, which would have a new unique number.

class BankAccount
{
protected:

const unsigned long int account_number;
char account_holder[30];

public:

BankAccount(char* in_account_holder) : account_number
(GenerateUniqueAccountNumber())
{
strcpy(in_account_holder, account_holder);
}

};
I know that my example is a bit crappy and you'd never have a class
like so or anything, but I hope it shows what I'm getting at.
-JKop


I also think that a const member is sometimes useful. I have one application for it in my self
made Type inquiry. There is a Type class with some const members that hold the information of
the type, like the baseclass, the name string and a unique code. Then there ist a constructor,
that defines them similar to the bank account example above. Finally I have a const static
member for every type in the library that looks like that:
static const Type Polynom;

and

const Type Type::Polynom = Type( 0xff0f0f0f, "Polynom", &ObjectBase );

The constructor arguments are the values for the const members.

I don't know about compiler optimization issues, but for me it is the information that const
gives to the programmer. When I take an objects type code like pDerivedPoly->GetType( )->Code
then its good to see it is const so it is not for change and it cannot be changed
accidentially.

But, I didn't find this by looking for a purpose for const members, so it is probably true to
say don't look for purposes for your tools, look for the tools you have a purpose for.
On the other hand, if you don't try and get to know all possibilities ( tools in your box ),
how can you know you choose the best one in a langluage that offers many ways to do the same
thing.

cheers
Ingo

Jul 22 '05 #11
Ben posted:
In a bank, the one sole piece of data by which a bank account is
identified is the account_number. After that, things like Balance and
Account Holder are just supplemental bits of data. You cannot change
an account's number, to do so would be change the one piece of data by
which the account can be identified. You would have to close the
account and open a new one, which would have a new unique number.

class BankAccount
{
protected:

const unsigned long int account_number;
char account_holder[30];

public:

BankAccount(char* in_account_holder) : account_number
(GenerateUniqueAccountNumber())
{
strcpy(in_account_holder, account_holder);
}

};


I understand that there are many business logics that require certain
field to be const or certain objects to be read-only.

The question is: is it wise to do that with "const member"? You are
sure your object will never be stored in a vector?
You are sure users never want to aggregate your object?

Yes, "this field should not change", but that can be implemented in
many ways. In c++, it is hard to say that something can never change.
Whatever the business requirement is, you may just want to be able to
change it for implementation reasons such as performance or
convenience. Say, swap.

class MyObject{
BankAccount acc;
void swap(MyObject& other){
//how do I write this if I cannot change acc?
}
};

How exactly users want to use this class should be decided by the
user. It sounds to me a too brave decision for the class designer to
say "no, I don't want it to be in a container. And no, don't aggregate
me!"

It makes more sense to say it cannot change in certain modules or
places or time, which, can be achieved by means of private/protected
and adapters.

Is it worthwhile to sacrifice flexibility for "security"? Talking
about security, with pointer arithmetics and casting present, nothing
is real secure anyway.

Well. it now sounds more something about personal flavor. One may
insist that he does not care the so-called "flexibility" and changing
one field is simply unacceptable, period. I have no disregard against
such decision.

I myself just always found I had to go back and change that decision,
however innocent it looked originally.


Could you please elaborate on how putting into into a container class could
complicate things? I've seen simple container classes before and all they do
is store a load of pointers to seperate objects. How will this intefer with
a const data member?!

-JKop
Jul 22 '05 #12
"Thomas Matthews" <Th*************************@sbcglobal.net> wrote in
message news:40**************@sbcglobal.net...
So, what would you use const instance member variable for? Do you use
it at all?

I use const member variables for {named} constants
used only within the class, member function or
global function.


Why not make those static const members?

FWIW I share the observations made by the OP ("static const is useful,
const methods are useful, const parameters are useful, const T* is useful,
but just cannot find niches for const member variables").

--
Peter van Merkerk
peter.van.merkerk(at)dse.nl


Jul 22 '05 #13
On 11 Jun 2004 17:32:58 -0700, be****@combined.com (Ben) wrote:
For many times, I've found myself changing my member variables from
const back to non-const. No matter how good the original objective
was, there was always at least one reason not to use const members.
(swap, storing it in a container, etc.)
Only value type objects generally offer those operations. Most objects
aren't value type objects.
Whereas in Java, 80% of the case, I would want "final" for my instance
variables.

It makes me think that is "const member variable" ever useful in C++?

Maybe because of the value semantics of C++ objects, immutable
programming is just not good for C++.

static const is useful, const methods are useful, const parameters are
useful, const T* is useful, but just cannot find niches for const
member variables.

So, what would you use const instance member variable for? Do you use
it at all?


Use it in business logic objects with immutable, per-instance values
that can be set in the initializer list.

Tom
--
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #14
be****@combined.com (Ben) wrote in message news:<24**************************@posting.google. com>...

class BankAccount
{
protected:

const unsigned long account_number;

public:

BankAccount(unsigned long in_account_number) : account_number
(in_account_number) { ; }

};


-JKop
This is similar to the stuff I normally start with. It looks innocent
to have "const member" here. However, later, you will find it hard to
store in a vector or an array. Users may complain it is hard to
aggregate your BankAccount object into their own objects when they do
want to change the bankaccount attribute.
In short, this BankAccount is only good for use as a stack object,
nothing else. And very rarely you will feel satisfied with that.

Again, it is the value semantics that kills the attempt to be
immutable.


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

You should distinguish between values and entities.
Bank accounts should be non-copyable entities:

class BankAccount
{
public:

const int id;

BankAccount(int id) : id(id) {}

private:

BankAccount(BankAccount&); // not implemented
BankAccount operator=(BankAccount&); // not implemented
};

Use (smart) pointers instead of values:

boost::shared_ptr<BankAccount>
In java, even your object is immutable, users can always do functional
update to get a new value if they want. And I do like that style. But
this is not possible in C++.

So, I'd like to conclude that "immutable programming" is dead in C++
and "const member variable" is very rarely useful or just useless.

Jul 22 '05 #15
Peter van Merkerk wrote:
"Thomas Matthews" <Th*************************@sbcglobal.net> wrote in
message news:40**************@sbcglobal.net...
So, what would you use const instance member variable for? Do you use
it at all?


I use const member variables for {named} constants
used only within the class, member function or
global function.

Why not make those static const members?

FWIW I share the observations made by the OP ("static const is useful,
const methods are useful, const parameters are useful, const T* is useful,
but just cannot find niches for const member variables").


I used to use const data members, but it wound up making the assignment
operator a nightmare.
Jul 22 '05 #16
Ben
> Could you please elaborate on how putting into into a container class could
complicate things? I've seen simple container classes before and all they do
is store a load of pointers to seperate objects. How will this intefer with
a const data member?!

-JKop


vector::push_back requires operator= to compile.
I believe some other template libs need some way to do "init - assign"
pattern as well rather than just raii it somewhere and never change it
again. (list, as an exception, does not require changing the object
once constructed, that is because, of course, list is using reference
semantics)
Jul 22 '05 #17
Ben
> Use (smart) pointers instead of values:

boost::shared_ptr<BankAccount>


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.

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.

I consider that flexibility very important.
Jul 22 '05 #18
Ben wrote:
For many times, I've found myself changing my member variables
from const back to non-const.
A const variable is an oxymoron.
An object is either a constant or a variable -- not both.
No matter how good the original objective was,
there was always at least one reason not to use const members.
I hope that they were *good* reasons.
(swap, storing it in a container, etc.) Whereas in Java,
80% of the case, I would want "final" for my instance variables.

It makes me think that is "const member variable" ever useful in C++?
Yes.

Maybe because of the value semantics of C++ objects,
immutable programming is just not good for C++.
No.

static const is useful, const methods are useful,
const parameters are useful, const T* is useful,
but just cannot find niches for const member variables.

So, what would you use const instance member variable for?
Do you use it at all?


I do.
Whether private data members are const or not
is important only to the class library developer.
You should begin your class design by making all data members const
then change them to variables
only after you find a good reason for doing so.
It shouldn't surprise you that many data members must be variables
if the object itself must be a variable sometimes.
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.
Jul 22 '05 #19
E. Robert Tisdale wrote:
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.
Jul 22 '05 #20
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
Jul 22 '05 #21
red floyd wrote:
E. Robert Tisdale wrote:
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.


You could be correct. It's hard to tell from what you wrote.
Maybe an example [code] would help.
Jul 22 '05 #22
JKop wrote:
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
Jul 22 '05 #23
Ben wrote:

For many times, I've found myself changing my member variables from
const back to non-const. No matter how good the original objective
was, there was always at least one reason not to use const members.
(swap, storing it in a container, etc.)
Whereas in Java, 80% of the case, I would want "final" for my instance
variables.

It makes me think that is "const member variable" ever useful in C++?

Maybe because of the value semantics of C++ objects, immutable
programming is just not good for C++.

static const is useful, const methods are useful, const parameters are
useful, const T* is useful, but just cannot find niches for const
member variables.

So, what would you use const instance member variable for? Do you use
it at all?


Off hand, I recall using it in the following pattern (an example
illustration):

class DataThing {
int get_data(int idx);

public:
//Proxy is not default- or copy-constructible
class Proxy {
DataThing& data_; //would be const if it wasn't for the ref.
int const base_idx_;

public:
Proxy(DataThing& data, int base_idx) : data_(data),
base_idx_(base_idx) {}
int get_data(int idx) {
return data_.get(base_idx_ + idx);
}
};

Proxy getAccessProxy(/*params*/) {
int base_idx;// = function of params
return Proxy(*this, base_idx);
}
//...
};

Denis
Jul 22 '05 #24
E. Robert Tisdale wrote:
red floyd wrote:
E. Robert Tisdale wrote:
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.

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


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?

Jul 22 '05 #25
be****@combined.com (Ben) wrote in message news:<24**************************@posting.google. com>...
Use (smart) pointers instead of values:

boost::shared_ptr<BankAccount>

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?
Jul 22 '05 #26
E. Robert Tisdale posted:
JKop wrote:
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

Jul 22 '05 #27
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.
Jul 22 '05 #28
"E. Robert Tisdale" <E.**************@jpl.nasa.gov> wrote in message news:<ca**********@nntp1.jpl.nasa.gov>...
Ben wrote:
For many times, I've found myself changing my member variables
from const back to non-const.


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.
Jul 22 '05 #29
In message <42**************************@posting.google.com >, ralpe
<ra************@gmx.net> writes
be****@combined.com (Ben) wrote in message
news:<24**************************@posting.google .com>...
>
> class BankAccount
> {
> protected:
>
> const unsigned long account_number;
>
> public:
>
> BankAccount(unsigned long in_account_number) : account_number
> (in_account_number) { ; }
>
> };
>
>
>
>
> -JKop


This is similar to the stuff I normally start with. It looks innocent
to have "const member" here. However, later, you will find it hard to
store in a vector or an array. Users may complain it is hard to
aggregate your BankAccount object into their own objects when they do
want to change the bankaccount attribute.
In short, this BankAccount is only good for use as a stack object,
nothing else. And very rarely you will feel satisfied with that.

Again, it is the value semantics that kills the attempt to be
immutable.


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


Exception safety and commit/rollback semantics?

--
Richard Herring
Jul 22 '05 #30
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

Jul 22 '05 #31
JKop <NU**@NULL.NULL> wrote in message news:<UD*****************@news.indigo.ie>...

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();
};
Jul 22 '05 #32

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

20
by: Corno | last post by:
Hi all, There's probably a good reason why a const object can call non const functions of the objects where it's member pointers point to. I just don't see it. For me, that makes the the const...
2
by: joe | last post by:
hi, after reading some articles and faq, i want to clarify myself what's correct(conform to standard) and what's not? or what should be correct but it isn't simply because compilers don't...
3
by: DanielBradley | last post by:
Hello all, I have recently been porting code from Linux to cygwin and came across a problem with static const class members (discussed below). I am seeking to determine whether I am programming...
7
by: Mark P | last post by:
The following compiles without error on four different platforms (Linux g++, Sun CC, HP aCC, Win Dev-C++) so I suspect it's ok, but I don't see why this isn't a const-related error. pB is a...
15
by: Jiří Paleček | last post by:
Hello, I know the rules for const handling in C++, but I'd like to ask what is the "right" way to use them, eg. when is it appropriate to make a member function const? This came across this...
2
by: Lionel B | last post by:
I have a function which takes a functor argument. I which to call it for a functor which is actually a class member; this works fine, using the mem_fun_ref and bind1st functions (see listing 1...
5
by: John Goche | last post by:
Hello, I would like to know whethere there is a difference between a const variable and a static const variable inside a class. After all, if a variable is const in a class, the compiler can...
23
by: Kira Yamato | last post by:
It is erroneous to think that const objects will have constant behaviors too. Consider the following snip of code: class Person { public: Person(); string get_name() const
2
by: Angus | last post by:
I have a member function, int GetLogLevel() which I thought I should change to int GetLogLevel() const - I made the change and it works fine. But in the function I am creating buffers and of...
12
by: hweekuan | last post by:
hi, it seems i can't assign the const variable u in class A, one way to solve the problem may be to build a copy constructor. however, why does C++ or vector class not like this code? my g++ is:...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.