|
-
July 22nd, 2004, 02:17 AM
#1
losing const
I'm working on some code for a library. I want to code it as correctly as possible to reduse the likelihood that someone will accidently write bad code and mess up internal data structures. Anyone here is a simplification of the code I have.
Code:
class A
{
public:
int someValue;
};
class B
{
public:
B(A value)
: a(value)
{ }
void SetValue(int value)
{
a.someValue = value;
}
private:
A a;
};
class C
{
public:
C()
: a()
{}
B const GetA() const
{
B const b(a);
return b;
}
private:
A a;
};
int main(void)
{
C const c;
B b(c.GetA()); // this shouldn't work
b.SetValue(10); // nor this and C is now changed even though it's const and no typecasting was done
return 0;
}
Where am I losing const which would allow the code in main() to compile? Also, any suggestions on how to force B to have to be B const for it to compile?
Thanks,
Scott MacMaster
-
July 22nd, 2004, 02:31 AM
#2
Because const is a type qualifier. Your code is actually calling:
Code:
B::B( const B& b );
in this line
Code:
B b(c.GetA()); // this shouldn't work
If you want the B in main to be non-modifiable declare it thus:
Code:
const B b( c.GetA() );
(you are using const after the type which though legal is unconventional).
If you want to have a "const class", i.e. a version whereby you can never call the non-const methods, you should split B into two classes.
Code:
class BConst
{
public:
BConst( A aIn ) : a( aIn ) {}
virtual ~BConst() {};
int getA() const { return a.SomeValue(); }
protected:
A a;
};
class B : public BConst
{
public:
B( A aIn ) : BConst( aIn ) {}
void setA( int i ) { a.someValue = i; }
};
class C
{
public:
const BConst getA() const; // etc
};
Your function will return a BConst on which nobody can call setA() because it's not a member of the class. This is how you might also implement read-only in idl (interface definition language) where const methods do not exist.
-
July 22nd, 2004, 02:36 AM
#3
you are using const after the type which though legal is unconventional
I've never seen that before, does 'const B b;' mean something different than 'B const b;' ?
- Matthias
"C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off." - Bjarne Stroustrup
-
July 22nd, 2004, 02:39 AM
#4
It surprises me that you haven't seen it, I think it's generally more conventional. They mean the same thing.
-
July 22nd, 2004, 03:04 AM
#5
 Originally Posted by matthias_k
I've never seen that before, does 'const B b;' mean something different than 'B const b;' ?
There is only different for pointer.
Code:
const char *p1 = "1st"; // pointer to char that is constant
char * const p2 = "2nd"; // const pointer to char
char const *p3 = "1st"; // same as p1.
p1[0] = '2'; // Compiler error.
p1 = "3rd"; // Ok.
p2 = "3rd"; // Compiler error.
-
July 23rd, 2004, 08:47 AM
#6
 Originally Posted by NMTop40
Because const is a type qualifier. Your code is actually calling:
Code:
B::B( const B& b );
in this line
Code:
B b(c.GetA()); // this shouldn't work
Ok, something did some correct about it. This explains why.
If you want the B in main to be non-modifiable declare it thus:
Code:
const B b( c.GetA() );
Yea, but I want callers of my code not to have to do that. So 'A' can't be modified. My code actually uses templates. If I could typecast TemplateClass<type> to TemplateClass<type const> I wouldn't have this problem with trying to find a way to do this. Any chance you know why that typecast isn't allowed?
If you want to have a "const class", i.e. a version whereby you can never call the non-const methods, you should split B into two classes.
After spending several hours trying things yesterday, that's what I ended up doing.
Thanks,
Scott MacMaster
-
July 23rd, 2004, 08:55 AM
#7
 Originally Posted by matthias_k
I've never seen that before, does 'const B b;' mean something different than 'B const b;' ?
No, it this case it doesn't. Some people think it unconventional but thatsonly because they learned c/c++ that way. Having const afterward is more natural for reading c/c++. If you have const to the right of the const component of the type you can read the type from right to left. Makes reading more complex types easier.
Examples:
B const variable; // variable is a constant object of type B
B const * const variable; // variable is a constant pointer to a constant object of type B
Later,
Scott MacMaster
-
July 23rd, 2004, 12:10 PM
#8
Yea, but I want callers of my code not to have to do that. So 'A' can't be modified. My code actually uses templates. If I could typecast TemplateClass<type> to TemplateClass<type const> I wouldn't have this problem with trying to find a way to do this. Any chance you know why that typecast isn't allowed?
I believe that the following thread might interest you. The relevant part is on page 2 of the thread:
http://www.codeguru.com/forum/showth...ighlight=const
**** **** **** **** **/**
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|