Explicit call of const member function



  • Hello.

    I have the following

    class C
    {
    private:
      ...some private declarations...
    public:
      char const *GetPointerToInternalData(int dataId) const
      {
        ...function body...
      }
    
      inline char *GetPointerToInternalData(int dataId)
      { //The same function as previous, but not const
        return const_cast<char *>(GetPointerToInternalData(id)); //Here I want to call const function!!!
      }
    };
    

    Obviously, the code does not works when I call GetPointerToInternalData() for non-const instance of class C, because this member function calls itself instead of calling const-version of it.

    The first question: what is the most easy way to specify which member-function I want to call: const or non-const?

    The second question: is this OK, that one of the const-overloaded functions is marked with inline, and other is not-inline?

    The third question: I have read somewhere that using of const_cast<> is bad manner, and I should avoid it. How can I achieve the same result (getting pointers to const data for const objects and regular pointers for non-const objects) without using const_cast<> and without duplicating the whole member-function body?

    Danke.


  • Mod

    SAn schrieb:

    Obviously, the code does not works when I call GetPointerToInternalData() for non-const instance of class C, because this member function calls itself instead of calling const-version of it.

    The first question: what is the most easy way to specify which member-function I want to call: const or non-const?

    Change the object argument such that overload resolution selects the const overload or select the right overload through a suitable pointer to member function.

    const C& r = *this; // or use a pointer
    return const_cast<char*>(r.GetPointerToInternalData(dataId));
    const char* (C::*pmf)(int) const = &C::GetPointerToInternalData;
    return const_cast<char*>((this->*pmf)(dataId));
    

    Instead of an additional declaration you could do it in a single expression too, using a static_cast or const_cast in the first case or a static_cast in the second case.

    The second question: is this OK, that one of the const-overloaded functions is marked with inline, and other is not-inline?

    Yes, other than having the same name, both functions are completely unrelated. Both functions are in fact inline anyway, because they have been defined within the definition of their class.

    The third question: I have read somewhere that using of const_cast<> is bad manner, and I should avoid it. How can I achieve the same result (getting pointers to const data for const objects and regular pointers for non-const objects) without using const_cast<> and without duplicating the whole member-function body?

    const_cast shouldn't be used to circumvent protection in code that is designed to be const-correct. That said, there's nothing wrong with judicious use of it in certain circumstances, implementing a non-const overload is such a legitimate use.



  • Thank you, Camper.

    camper schrieb:

    const char* (C::*pmf)(int) const = &C::GetPointerToInternalData;
    return const_cast<char*>((this->*pmf)(dataId));
    

    Pointers to member functions have always been hard for me. Just curious, how compiler will decide which function we are getting pointer to in the first line of the code?


  • Mod

    SAn schrieb:

    Thank you, Camper.

    camper schrieb:

    const char* (C::*pmf)(int) const = &C::GetPointerToInternalData;
    return const_cast<char*>((this->*pmf)(dataId));
    

    Pointers to member functions have always been hard for me. Just curious, how compiler will decide which function we are getting pointer to in the first line of the code?

    Well, no sane programmer would use that version, I mentioned it for completeness. The expression &C::GetPointerToInternalData by itself does not point to one particular function of an overload set (the same is true if we have ordinary functions that have been overloaded), therefore the correct overload ist determined by the context in with the expression appears. That is, if we initialise a pointer to member function or pointer to function (X::Y might refer to a static member function after all), the type of the pointer determines which overload is used. Similarly, a cast can be used instead.


Anmelden zum Antworten