分享

c – static_cast(* this)和static_cast(* this)之间的区别

 印度阿三17 2019-08-27

在以下代码中(取自有效的C):

class A 
{
  ....
  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[]
      );
  }

  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;
}

在此代码中,如果您从const TextBlock&更改static_cast;对于const TextBlock,这会导致operator []的非const版本被递归调用.任何人都可以解释这背后的原因是什么(为什么const TextBlock导致不调用const成员函数operator []).

解决方法:

原因是因为

const A a();

A b();

是不同的对象,并且在CPP非常量对象中不能调用常量函数,反之亦然;因此,您需要为const和非const对象分别声明两次相同的函数.

cout << a[0] << endl;

是合法的,但是

cout << b[0] << endl;

不是.
因此,您应该为非const对象重载[]运算符.为了避免复制代码,作者建议通过抛弃其constness来使用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&amp ;.因此施放常数

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的隐式转换,因此你可以替换:

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-casted对象返回一个非const引用,该对象调用一个重载的运算符[] :)正是因为这个原因你不能使用

return const_cast <char &> ((*this)[position]);

因为这是一个非const对象;因此,它将调用非成本函数(重载operator []),这将导致无限递归.

希望它有意义.

来源:https://www./content-4-415151.html

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多