C++ difference between adding const-ness with static_cast and const_cast of “this” object?

前端 未结 2 806
猫巷女王i
猫巷女王i 2021-02-05 15:32

As per Scott Meyers, to prevent repetition of code in the const version of a getter and the non-const version of a getter, call the const version of the method from the non-cons

2条回答
  •  遇见更好的自我
    2021-02-05 15:46

    After re-reading Item 3 from Effective C++ 3rd Ed. I realize that he was actually advocating using both. Add const to call the const version, then cast away the const-ness of the return value (if there is one). In my particular case, there is no const return value, just a const-function so the wrapped-by-const_cast<> version is not needed and in effect causes there to be no difference between the two calls in question

    (p. 13) Item 3: Use const whenever possible

    ...

    (p. 23) Avoiding Duplication in const and Non- const Member Functions

    ...What you really want to do is implement operator[] functionality once and use it twice. That is, you want to have one version of operator[] call the other one. And that brings us to casting away constness.

    ...Casting away the const on the return value is safe, in this case, because whoever called the non-const operator[] must have had a non-const object in the first place....So having the non-const operator[] call the const version is a safe way to avoid code duplication, even though it requires a cast...

    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[]
        {
            //cast away const on op[]'s return type;
            //add const to *this's type;
            //call const version of op[].
            return const_cast(static_cast(*this)[position]);
        }
    ...
    };
    

    As you can see, the code has two casts, not one. We want the non-const operator[] ... To avoid infinite recursion, we have to specify that we want to call the const operator[], but there's no direct way to do that. Instead, we cast *this from its native type of TextBlock& to const TextBlock&. Yes, we use cast to add const! So we have two casts: one to add const to *this (so that our call to operator[] will call the const version), the second to remove the const from the *const operator[]'s return value.

提交回复
热议问题