当没有非常量运算符重载时,非常量对象将使用常量运算符

When there is no non-const operator overload, will non-const object use const operator?

本文关键字:常量 运算符 非常 对象 重载      更新时间:2023-10-16

>似乎在VS2013中。但是,为什么在有效的 c++ 第 3 项中,非常量运算符在执行完全相同的操作时调用 const 运算符?

这是有效 c++ 项 3 中的代码:

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 type;
static_cast<const TextBlock&>(*this)[position]  // add const to *this's type;call const version of op[]
);
}
...
};

const对象不能使用非const方法。(请记住,运算符只是方法)。

但反之然:非const对象可以使用const方法(尽管如果存在,它将使用非const等效方法)。

只有当方法被标记为const,它才会被const:不允许编译器通过检查函数体来断言const性。

是:如果存在const成员函数,但没有非const版本,则在非const对象上调用该函数将使用const函数。

#include <iostream>
struct Foo {
    void bar() const { std::cout << "const bar()n"; }
};
int main() {
    Foo f;
    f.bar();
}

打印const bar() .

请注意,反之则然。不能const对象上调用非const成员函数:

struct Foo {
    void bar() { std::cout << "non-const bar()n"; }
};
int main() {
    const Foo f;
    f.bar();
}

给出编译器错误:

SO.cpp: In function 'int main()':
SO.cpp:9:11: error: passing 'const Foo' as 'this' argument of 'void Foo::bar()' discards qualifiers [-fpermissive]
     f.bar();
           ^

EC++ 第 3 项"尽可能使用const"有一个小节,避免const和非const成员函数中的重复。它建议你不要只让编译器选择const版本的原因是返回类型不同(按const) - 非const版本会抛弃这一点:

class CharWrapper {
    char c_;
  public:
    char const& getC() const
    {
        std::cout << "const getC()n";
        return c_; // pretend this line is complicated
    }
    char& getC()
    {
        std::cout << "non-const getC()n";
        char const& c = const_cast<CharWrapper const&>(*this).getC(); // call the right one to avoid duplicating the work
        return const_cast<char&>(c); // fix the result type
    }
};
int main() {
    CharWrapper wrapper;
    wrapper.getC() = 'a';
}

请注意,它调用 const 运算符并丢弃恒常性(它是少数不会导致 UB 的情况之一)。需要它,以便非常量运算符返回可变引用。否则,您将根本无法修改 vector 中包含的对象。

调用现有运算符而不是再次编写代码是为了避免代码重复和将来更改一个函数时可能出现的错误,但忘记了另一个函数。

关于您的评论:不涉及任何移动。它返回一个引用。我希望 const 和非 const 运算符的生成代码没有区别。