c++ - static_cast<const A>(*this) 和 static_cast<const A&>(*this) 的区别

标签 c++ pointers static this casting

在以下代码中(取自有效的 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;
}

在此代码中,如果将 static_cast 从 const TextBlock& 更改为 const TextBlock,这将导致非 const 版本的 operator[] 被递归调用。谁能解释这背后的原因(为什么 const TextBlock 导致不调用 const 成员函数 operator[] )。

最佳答案

原因是因为

const A a();

A b();

是不同的对象,在 CPP 中非常量对象不能调用常量函数,反之亦然;因此,您需要分别为 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 函数的 []operator 返回 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]);

这将从这个调用重载运算符 [] 的常量转换对象返回一个非常量引用到 char :) 正是因为这个原因你不能使用

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

因为这是一个非常量对象;因此,它将调用非成本函数(重载运算符[]),这将导致无限递归。

希望这是有道理的。

关于c++ - static_cast<const A>(*this) 和 static_cast<const A&>(*this) 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3802556/

相关文章:

c++ - 静态全局变量的奇怪行为

c# - MAKEWORD c++ Windows 宏的 C# 等价物是什么?

c++ - 在列表中查找特定项目

c++ - 正则表达式检测 typedef/class 关键字之后的任何内容?

在 C 中将缓冲区作为函数调用?

java - 使用反射访问静态最终变量

java - 初始化 ArrayList 的静态映射

C++ - 在运行时展开堆栈

c - 使用远指针在 C 中设计键盘记录器

c - 遍历c中的结构