char greeting[] = "Hello";
char *p = greeting; // non-const pointer,
// non-const data
const char *p = greeting; // non-const pointer,
// const data
char * const p = greeting; // const pointer,
// non-const data
const char * const p = greeting; // const pointer,
// const data
void f1(const Widget *pw); // f1 takes a pointer to a
// constant Widget object
void f2(Widget const *pw); // so does f2
std::vector<int> vec;
...
const std::vector<int>::iterator iter = // iter acts like a T* const
vec.begin();
*iter = 10; // OK, changes what iter points to
++iter; // error! iter is const
std::vector<int>::const_iterator cIter = //cIter acts like a const T*
vec.begin();
*cIter = 10; // error! *cIter is const
++cIter; // fine, changes cIter
class Rational { ... };
const Rational operator*(const Rational& lhs, const Rational& rhs);
Rational a, b, c;
...
(a * b) = c; // invoke operator= on the
// result of a*b!
if (a * b = c) ... // oops, meant to do a comparison!
class TextBlock {
public:
...
const char& operator[](std::size_t position) const // operator[] for
{ return text[position]; } // const objects
char& operator[](std::size_t position) // operator[] for
{ return text[position]; } // non-const objects
PRivate:
std::string text;
};
TextBlock tb("Hello");
std::cout << tb[0]; // calls non-const
// TextBlock::operator[]
const TextBlock ctb("World");
std::cout << ctb[0]; // calls const TextBlock::operator[]
void print(const TextBlock& ctb) // in this function, ctb is const
{
std::cout << ctb[0]; // calls const TextBlock::operator[]
...
}
std::cout << tb[0]; // fine - reading a
// non-const TextBlock
tb[0] = ’x’; // fine - writing a
// non-const TextBlock
std::cout << ctb[0]; // fine - reading a
// const TextBlock
ctb[0] = ’x’; // error! - writing a
// const TextBlock
tb[0] = ’x’;
class CTextBlock {
public:
...
char& operator[](std::size_t position) const // inappropriate (but bitwise
{ return pText[position]; } // const) declaration of
// operator[]
private:
char *pText;
};
const CTextBlock cctb("Hello"); // declare constant object
char *pc = &cctb[0]; // call the const operator[] to get a
// pointer to cctb’s data
*pc = ’J’; // cctb now has the value "Jello"
class CTextBlock {
public:
..
std::size_t length() const;
private:
char *pText;
std::size_t textLength; // last calculated length of textblock
bool lengthIsValid; // whether length is currently valid
};
std::size_t CTextBlock::length() const
{
if (!lengthIsValid) {
textLength = std::strlen(pText); // error! can’t assign to textLength
lengthIsValid = true; // and lengthIsValid in a const
} // member function
return textLength;
}
class CTextBlock {
public:
...
std::size_t length() const;
private:
char *pText;
mutable std::size_t textLength; // these data members may
mutable bool lengthIsValid; // always be modified, even in
}; // const member functions
std::size_t CTextBlock::length() const
{
if (!lengthIsValid) {
textLength = std::strlen(pText); // now fine
lengthIsValid = true; // also fine
}
return textLength;
}
class TextBlock {
public:
..
const char& operator[](std::size_t position) const
{
... // do bounds checking
... // log access data
... // verify data integrity
return text[position];
}
char& operator[](std::size_t position)
{
... // do bounds checking
... // log access data
... // verify data integrity
return text[position];
}
private:
std::string text;
};
class TextBlock {
public:
...
const char& operator[](std::size_t position) const // same as before
{
...
...
...
return text[position];
}
char& operator[](std::size_t position) // now just calls const op[]
{
return
const_cast<char&>( // cast away const on
// op[]’s return type;
static_cast<const TextBlock&>(*this) // add const to *this’s type;
[position] // call const version of op[]
);
}
...
};
新闻热点
疑难解答