What are the known shortfalls of const
in C++ and C++0x?
相关问题
- Sorting 3 numbers without branching [closed]
- How to compile C++ code in GDB?
- Why does const allow implicit conversion of refere
- thread_local variables initialization
- What uses more memory in c++? An 2 ints or 2 funct
相关文章
- Class layout in C++: Why are members sometimes ord
- How to mock methods return object with deleted cop
- Which is the best way to multiply a large and spar
- C++ default constructor does not initialize pointe
- Selecting only the first few characters in a strin
- What exactly do pointers store? (C++)
- Converting glm::lookat matrix to quaternion and ba
- What is the correct way to declare and use a FILE
The two main issues that I have seen frequent complaints about in newsgroups, are
The need to waste a lot of time on supporting non-const-aware APIs (especially Microsoft's).
The need to define both const and non-const version of a method.
I think the latter could/should be supported by the language.
Possibly in conjunction with support for covariant member function implementations, because both need some way to pick up the type of the
this
pointer.A third issue is that
Cheers & hth.,
What's wrong with
const
is that many programmers don't seem to be able to understand it completely, and a "half-const-correct" project simply does not work. This is what you need to know:Foo
vs.const Foo
(orFoo const
)Foo&
vs.const Foo&
(orFoo const&
)Foo*
vs.const Foo*
(orFoo const*
)Foo* const
andconst Foo* const
(orFoo const* const
)void Foo::mutator()
vs.int Foo::accessor() const
iterator
vs.const_iterator
const iterator
andconst const_iterator
Migrating to C++ from a language that has no const concept is quite hard, any many fail to see the point.
One thing that is "wrong" is that you cannot convert T** to T const * const * which should be allowed because it is not dangerous. Not allowing T** to convert to T const ** is correct, that conversion is not valid.
I have sometimes mentioned that const actually is a cheap way to "split" your interface into read-only methods and write methods. It would probably be impractical in C++. It would be more practical in Java to have ReadOnly versions of collections though, where they don't have const and where their collection types are more object-orientated.
const-ness does not propagate: The issue here is that if I pImpl my class, the constness is not "checked" by the compiler, i.e. my interface class can have a "const" method call a non-const method on the pImpl and the compiler won't complain. That is because the only thing my const method is guaranteed not to do is change the pointer to point to a different object, and my pImpl is never going to change. It could even be a const pointer (not pointer to const).
The lack of proper co-variance between
shared_ptr<T>
andshared_ptr<const T>
might be an issue too, although in general I have seen that not to be the problem, but that developers usually typedef their shared_ptrs and rarely typedef the shared_ptr to const. And they will sometimes passconst shared_ptr<T> &
and think that they are passing a shared pointer to a const T (as with const T*) which they are not."issues"?
If you aren't going to be modifying the value of a passed pointer (it is used purely for pass-by-reference input to a function), mark it is
const
. Ditto if the value of a particular variable will not change after its initialization. If a function is safe to call on aconst
class instance, mark itconst
too. The more items are correctly annotatedconst
, the less likely you are to inadvertently make a mistake and the more optimizations the compiler will be theoretically able to perform in the absence of complete knowledge (such as when compiling with only function prototypes available).Modern versions of gcc have support for warning when you try to cast a
const
variable to a non-const
one. I suggest you leave those warnings enabled.The only thing to watch out for is exactly what you are marking
const
;const char * foo()
is not the same aschar * foo() const
.Another problem that has not been mentioned yet is the possibility for a badly designed interface to subvert const (even in the absence of casts).
Example:
The intransitive nature of const means that it is possible to have an interface where a non-const reference to an object can be obtained from a const reference to an object. This is something to be careful of when designing interfaces.
One problem is that the language also lets you const_cast it away, which defeats the purpose of using const in the first place.