C++ 通过父类型指针或直接从派生类访问成员函数的差异

C++ 通过父类型指针或直接从派生类访问成员函数的差异,c++,C++,考虑三个类A、B和C,其中A是B和C的父类,其函数A::doThing() 以下两种调用doThing()的方法在性能方面是否有区别(假设B和C不重写doThing() 在一个教程应用程序中,我看到他们声称第二种方法更快。我知道如果B或C覆盖doThing(),那么两种不同的调用可能会有不同的结果,但我不明白为什么第二种调用函数的方法会更快?直接引用(在示例中,他们使用选项2): 如果直接在对象上调用函数,我们也会得到同样的结果。但是,使用指针更快、更有效 编辑:来自应用程序的代码,有些人认为我

考虑三个类
A
B
C
,其中
A
B
C
的父类,其函数
A::doThing()

以下两种调用
doThing()
的方法在性能方面是否有区别(假设
B
C
不重写
doThing()

在一个教程应用程序中,我看到他们声称第二种方法更快。我知道如果B或C覆盖
doThing()
,那么两种不同的调用可能会有不同的结果,但我不明白为什么第二种调用函数的方法会更快?直接引用(在示例中,他们使用选项2):

如果直接在对象上调用函数,我们也会得到同样的结果。但是,使用指针更快、更有效

编辑:来自应用程序的代码,有些人认为我误解了:

#include <iostream>
using namespace std;

class Enemy {
    protected: 
        int attackPower;
    public:
        void setAttackPower(int a){
            attackPower = a;
        }
};

class Ninja: public Enemy {
    public:
        void attack() {
            cout << "Ninja! - "<<attackPower<<endl;
        }
};

class Monster: public Enemy {
    public:
        void attack() {
            cout << "Monster! - "<<attackPower<<endl;
        }
};

int main() {
    Ninja n;
    Monster m;
    Enemy *e1 = &n;
    Enemy *e2 = &m;

    e1->setAttackPower(20);
    e2->setAttackPower(80);

    n.attack();
    m.attack();
}
#包括
使用名称空间std;
阶级敌人{
受保护的:
国际攻击力;
公众:
无效设置攻击能力(int a){
攻击力=a;
}
};
忍者类:公敌{
公众:
无效攻击(){

cout如果
doThing
不是
virtual
,则一切都是一样的,因为在所有情况下,调用的确切方法都是在编译时解析的

否则:

  • 直接调用对象应该总是尽可能快,因为编译器确定对象的实际类型,所以并没有额外的间接步骤(并没有vtable查找,可能的内联)
  • 当通过指向基类的指针调用时,取决于编译器证明对象动态类型的能力(或者认识到该方法永远不会被重写);这可能很容易,但很快就会变得困难(对于编译器来说,理解没有人在重新定义虚拟方法甚至不是一件小事,因为除了LTCG和类似的机制,它不知道在其他翻译单元中发生了什么)
如果直接在对象上调用函数,我们也会得到同样的结果。但是,使用指针更快、更有效


如果上下文如你所述,这完全是胡说八道。扔掉任何在哪里找到的指南,作者都不知道他在说什么。

你能告诉我那句话的来源吗..我想起诉作者不称职,在这个例子中,
是在做
虚拟的吗?我同意。你应该停止使用它源代码,不管它是什么,学习C++。这个来源根本不理解C++,你应该得到一个简单的承认潜在的愚蠢,并无辜地询问它。你的直觉是正确的,应该是。不,它不是代码>虚拟< /代码>,它是在<代码> A<代码> >代码> > <代码>。OURCE是学习C++的Android应用程序,我以前使用它来提高语法速度,但对其他任何东西都没有帮助。你可以考虑对Android应用程序进行评论,提到StasOfFuffo.com上的每个人都在嘲笑它的智慧之珠。如果你真的想学究式的话,那就可以B了。e不同之处在于
B
C
定义自己的成员函数
doThing
。由于
a::doThing
不是虚拟的,因此此类定义不构成覆盖(如OP所要求),但其效果是
b1.doThing()
a->doThing()
调用不同的函数。@KerrekSB:当然,我的“一切都一样”实际上只是指函数调用性能的观点。
#include <iostream>
using namespace std;

class Enemy {
    protected: 
        int attackPower;
    public:
        void setAttackPower(int a){
            attackPower = a;
        }
};

class Ninja: public Enemy {
    public:
        void attack() {
            cout << "Ninja! - "<<attackPower<<endl;
        }
};

class Monster: public Enemy {
    public:
        void attack() {
            cout << "Monster! - "<<attackPower<<endl;
        }
};

int main() {
    Ninja n;
    Monster m;
    Enemy *e1 = &n;
    Enemy *e2 = &m;

    e1->setAttackPower(20);
    e2->setAttackPower(80);

    n.attack();
    m.attack();
}