C++ C++;虚函数:调用基类函数而不是派生

C++ C++;虚函数:调用基类函数而不是派生,c++,c++11,inheritance,virtual-functions,overload-resolution,C++,C++11,Inheritance,Virtual Functions,Overload Resolution,我有以下代码片段: class base { public: virtual void print(char a){ std::cout << " Base\n"; } }; class derived : public base { public: void print(float a) { std::cout << " Derived\n"; } }; int main() { base* d =

我有以下代码片段:

class base
{
public:
    virtual void print(char a){ std::cout << " Base\n"; }
};

class derived : public base
{
public:
    void print(float a)  { std::cout << " Derived\n"; }
};

int main() {
    base* d = new derived;
    d->print(1.5);
}
类基
{
公众:

virtual void print(char a){std::cout当您声明
Base*d=new-Derived;
时,类的类型是Base,由
typeid(d).name()打印,因此此实例无权访问子类方法。如果将类型更改为Derived,您将调用子方法:

#include <iostream>
#include <typeinfo>

class Base
{
  public:
    virtual void print(char a) {
        std::cout << " Base " << std::endl;
    }
};

class Derived : public Base
{
  public:
    void print(float a) {
        std::cout << " Derived " << std::endl;
    }
};

int main()
{
    Derived* d = new Derived;
    std::cout << "class type is: " << typeid(d).name() << std::endl;
    d->print(1.5);

    return 0;
}
此外,声明父类
print
方法
virtual
不允许Base实例调用
print
的子版本,因为子版本没有覆盖它(不同的头).使用
Base*d=new-Derived;
创建Base实例,并将派生的
print
方法头更改为
void print(字符a)派生类中的
允许您调用子
print
方法并使用
virtual
关键字输出
派生的
,甚至可以从Base的实例中输出

#include <iostream>
#include <typeinfo>

class Base
{
  public:
    virtual void print(char a) {
        std::cout << " Base " << std::endl;
    }
};

class Derived : public Base
{
  public:
    void print(char a) {
        std::cout << " Derived " << std::endl;
    }
};

int main()
{
    Base* d = new Derived;
    std::cout << "class type is: " << typeid(d).name() << std::endl;
        d->print(1.5);

    return 0;
}

您没有重写基类中的函数,而是重载了它:派生类中的版本采用
浮点
作为参数,与采用
字符
的基类方法截然不同。此外,派生类中的
浮点
版本阴影基类版本:对于派生类型的调用,基类版本变得不可访问

因此,下面的代码

Derived d;
d.print('a');
d.print(1.5);
将打印

Derived
Derived
因为编译器将调用解析为
派生的
中可用的唯一版本的
print()

同样,当您通过指向
Base
的指针调用
d->print(1.5)
时,调用无法访问派生类的版本:编译器查看基类,发现没有
print()
方法使用
float
参数定义,并将参数转换为
char
。然后它调用
打印(char)
的唯一实现,该实现恰好由基类提供



如果您只是更改
print()的签名
方法在派生类中匹配基类,奇怪的行为将消失。

我认为没有任何条件要求名称以大写字母开头。其次,在派生类中,两个版本都应该存在,然后float比char更匹配。不是从编译器的角度来看(你可以把所有的东西命名为随机的胡言乱语,它会是100%的快乐),但是从人类的角度来看,这是标准的约定(打开任何C++书籍或查看Github或堆栈溢出上的任何C++代码)。在第二点上:你的问题和预期输出是什么?那么,在我看来你期待看到“派生”。但如果不是这样的话,你在问什么?我同意你的看法,因为最佳编码实践是这样的。我的问题是,为什么在这种情况下输出是“基”,为什么不是“派生”?啊,我看得更清楚一点。我会试着编辑。谢谢。“将打印”。不是真的。试试。@n.“代词m.啊,好的捕获:-)完全忘记了阴影。将更新我的答案以处理此问题。谢谢。@n.“代词已完成。”。