在学多态的时候遇到了问题。按理说
父类的成员函数不加virtual时,访问的还是父类的成员函数,而不是子类同名的成员函数;
没有添加virtual关键字,则编译器直接按照类型来调用对应的函数,不会考虑多态特性。
比如这段代码,输出就是基类的成员函数结果:
#include <iostream>
#include <string>
#include <string_view>
class Animal
{
protected:
std::string m_name;
// We're making this constructor protected because
// we don't want people creating Animal objects directly,
// but we still want derived classes to be able to use it.
Animal(const std::string& name)
: m_name{ name }
{
}
public:
const std::string& getName() const { return m_name; }
// 父类的成员函数不加virtual时,访问的还是父类的成员函数,而不是子类同名的成员函数
// 没有添加virtual关键字,则编译器直接按照类型来调用对应的函数,不会考虑多态特性。
std::string_view speak() const { return "???"; }
};
class Cat: public Animal
{
public:
Cat(const std::string& name)
: Animal{ name }
{
}
std::string_view speak() const { return "Meow"; }
};
class Dog: public Animal
{
public:
Dog(const std::string& name)
: Animal{ name }
{
}
std::string_view speak() const { return "Woof"; }
};
void report(const Animal& animal)
{
std::cout << animal.getName() << " says " << animal.speak() << '\n';
}
int main()
{
Cat cat{ "Fred" };
Dog dog{ "Garbo" };
report(cat);
report(dog);
return 0;
}
但是反观这段代码,getName()是可以被成功override的:
#include <string_view>
#include <iostream>
class Base
{
protected:
int m_value {};
public:
Base(int value)
: m_value{ value }
{
}
std::string_view getName() const { return "Base"; }
int getValue() const { return m_value; }
};
class Derived: public Base
{
public:
Derived(int value)
: Base{ value }
{
}
std::string_view getName() const { return "Derived"; }
int getValueDoubled() const { return m_value * 2; }
};
int main()
{
Derived derived{ 5 };
std::cout << "derived is a " << derived.getName() << " and has value " << derived.getValue() << '\n';
Derived& rDerived{ derived };
std::cout << "rDerived is a " << rDerived.getName() << " and has value " << rDerived.getValue() << '\n';
Derived* pDerived{ &derived };
std::cout << "pDerived is a " << pDerived->getName() << " and has value " << pDerived->getValue() << '\n';
return 0;
}
实际要看report()中传入的是哪一个类的引用。