The difference between static_cast <const A> (* this) and static_cast <const A &> (* this)
in the following code (taken from efficient C ++):
class A
{
....
char& operator[](std::size_t position) // now just calls const op[]
{
return
const_cast<char&>( // cast away const on op[] return type;
static_cast<const TextBlock&>(*this) // add const to *this type;
[position] // call const version of op[]
);
}
const char& operator[](int index) const
{
...
}
}
//complete example, tested with VC 2010
#include<iostream>
#include<string>
class TextBlock
{
public:
TextBlock(std::string st):text(st){};
TextBlock(char* cstr): text(cstr){};
TextBlock(const TextBlock& r)
{
std::cout<<"copy constructor called"<<std::endl;
}
char& operator[](int index)
{
std::cout<<"non-const operator"<<std::endl;
return const_cast<char&>(static_cast<const TextBlock>(*this)[index]);
}
const char& operator[](int index) const
{
std::cout<<"const operator"<<std::endl;
return text[index];
}
private:
std::string text;
};
int main()
{
TextBlock rt("hello");
std::cout<<rt[0]<<std::endl;
}
In this code, if you change the static_cast from const TextBlock & to const TextBlock, this leads to a non-constant version of the [] operator, called recursively. Can anyone explain what the reason for this is (why const TextBlock leads to the fact that the const member statement does not work []).
The reason is that
const A a();
and
A b();
- , CPP ; , const non-const .
cout << a[0] << endl;
,
cout << b[0] << endl;
. [] . , const, . :
char& operator[](std::size_t position)
{
return const_cast <char &>( static_cast <const A &>(*this) [position] );
}
, const
char& operator[](std::size_t position)
{
const A temp = *this; //create a const object
//and assign current object to it
....
}
[] const obj
char& operator[](std::size_t position)
{
const A temp = *this; //create a const object
//and assign current object to it
return temp[position]; // call an overloaded operator []
// of the const function
}
, [] const const char & char &. ,
char& operator[](std::size_t position)
{
const A temp = *this; //create a const object
//and assign current object to it
return const_cast <char &>( temp[position] );
}
. : "
const A temp = *this;
return const_cast <char &> (temp[position]);
:
return const_cast <char &> ( static_cast <const A &> (*this)[position]);
? , temp - const, :
const A temp = *this; // implicit cast
const A temp = static_cast <const A &> (*this) //explicit
:
const A temp = const_cast <const A &> (*this)
- :
return const_cast <char &> (static_cast <const A &>(*this)[position]);
-const ref char const-casted, []:)
return const_cast <char &> ((*this)[position]);
-const-; ( []), .
, .
[],
, const, const const:
const TextBlock a("Hello");
TextBlock b("World");
a[0] b[0], operator[]. - a[0] const:
const char &operator[](int) const;
a const, . , [], const const char&, , .
, - b[0] const:
char &operator[](int);
, . , char &, .
?
, const. non-const const.
, , const . static_cast<>. , b const TextBlock, const.
char &operator[](int index)
, .
char & operator[](int position)
{
// const TextBlock tmp = *this;
// return const_cast<char &>(tmp[position]);
return
const_cast<char &>( (static_cast<const TextBlock &>(*this))[position] );
}
static_cast<const TextBlock &>(*this) , TextBlock & to const TextBlock & *this.
, tmp. tmp[0] const, .
const , const char &. char &. const_cast<char &> const . char, .
, return :
const TextBlcok &tmp = *this;
return const_cast<char &>tmp[position];
tmp - * this ( ). TextBlock & const TextBlock & , return .
& , , . . , tmp *this. , . , tmp, , , !
, char, reko_t, - g++ 3.4.6.
...
static_cast<const TextBlock>(*this)
... , ...
const TextBlock temporary = *this;
... . . , , undefined.
? ( , int, ).
#include <iostream>
struct A
{
char operator[](int position) // now just calls const op[]
{
return
static_cast<const A>(*this) // add const to *this type;
[position]; // call const version of op[]
}
const char operator[](int index) const
{
return x_[index];
}
char x_[10];
};
int main()
{
A a;
strcpy(a.x_, "hello!");
const A& ca = a;
std::cout << a[0] << ca[1] << a[2] << ca[3] << a[4] << ca[5] << '\n';
}
char& operator[](std::size_t position) char& operator[](std::size_t position) const . "const" . - "" , - const . , , const- , const.
const A a;
char c = a[i]; // Calls the const version
A b;
char d = b[i]; // Calls the non-const version
(* this) [position] , , . , const .
EDIT: .. , , . - ? , .
EDIT2: , .
a [i] → const cast (const A) → temp [position] → const cast → temp2 [position] → .....
, const (const A &), , .
...
static_cast<const TextBlock>(*this)[position];
:
- * const TextBlock
- , const TextBlock (-, const TextBlock)
- [] , , .
- .
Your operators have different types of parameters
char & operator [] (position std :: size_t)
const char & operator [] (int index) const <- Should also be std :: size_t
This may be the solution you are looking for. Was there an example from the book for different parameters of different types? Remember that casting type works with return value.
char& operator[](std::size_t index)
{
std::cout<<"non-const operator"<<std::endl;
const TextBlock & ref = *this;
return const_cast<char&>(ref[index]);
}