virtual function that is const in the base class and not const in the derived

后端 未结 6 1404
庸人自扰
庸人自扰 2021-02-08 09:54

Can anyone explain the output of the following code?

#include 
#include 
class Animal
{
public:
    Animal(const std::string &          


        
6条回答
  •  一个人的身影
    2021-02-08 10:43

    It took me a while to understand Peter Alexander's hiding answer, but another way to understand it is as follows:

    Say that you mispelled the method name in the Cow class, but spelled it correctly in Animal class:

    Animal::printMessage()
    Cow::mispelledPrintMessage()
    

    then when you have an

    Animal *animal;
    

    you can ONLY call

    animal->printMessage();
    

    but you CANNOT call

    animal->mispelledPrintMessage();
    

    because mispelledPrintMessage() doesn't exist in the Animal class. Its a brand new method in the Cow class, so it cannot be polymorphically called thru a base pointer.

    So having the Animal method have const in the signature, but not in Cow method is kinda analogous to a slightly mispelled method name in the derived class.

    PS: Another 4th solution (1 making both methods const, 2 making both methods non-const, or 3 using new 2011 override keyword), is to use a cast, to force the Animal pointer into a Cow pointer:

    ((Cow*)animal)->printMessage();
    

    But this is a very ugly HACK, and I would not recommend it.

    PS: I always try to write my toString() methods with const in the signature in the Base class and all derived classes for this very reason. Plus, having const in the toString() signature allows you call toString() either with a const or non-const object. Had you instead left out the const, and tried to pass call toString() with a const object, GCC compiler would complain with the discards qualifiers error message:

    const Bad' as `this' argument of `std::string Bad::toString()' discards qualifiers
    

    for this code:

    #include 
    #include 
    
    class Bad
    {
    public:
            std::string toString()
            {
                    return "";
            }
    };
    
    int main()
    {
            const Bad       bad;
            std::cout << bad.toString() << "\n";
            return 0;
    }
    

    So, in conclusion, since Cow doesn't change any data members, the best solution probably is to add const to printMessage() in derived Cow class, so that both BASE Animal and DERIVED Cow classes have const in their signatures.

    -dennis bednar -ahd 310

提交回复
热议问题