C++ 在基类的对象上调用派生类的方法

C++ 在基类的对象上调用派生类的方法,c++,linux,inheritance,gcc,vtable,C++,Linux,Inheritance,Gcc,Vtable,我已经写了几行我认为不应该编译的代码。我在指向基类对象的静态强制转换指针上调用派生类的方法,如下所示: class B {}; class D: public B { public: void bar() { printf("%d\n", m_i); } private: int m_i; }; int main() { B b; D* d = static_cast<D*>(&b); d->bar(); re

我已经写了几行我认为不应该编译的代码。我在指向基类对象的静态强制转换指针上调用派生类的方法,如下所示:

class B {};    

class D: public B
{
public:
    void bar() { printf("%d\n", m_i); }
private:
    int m_i;
};

int main()
{
    B b;
    D* d = static_cast<D*>(&b);
    d->bar();
    return 0;
}
B类{};
D类:公共B类
{
公众:
void bar(){printf(“%d\n”,m_i);}
私人:
国际货币基金组织;
};
int main()
{
B B;
D*D=静态施法(&b);
d->bar();
返回0;
}

打印的值显然是垃圾,但这是否应该编译?gcc如何做到这一点

使用static\u cast,您告诉编译器“我知道我在做什么,B*实际上是D*,闭嘴,照我说的去做。”

gcc
不能保证它是错误的,除非在少数情况下它确实不值得检查。当您使用
static\u cast
时,您就是在向编译器承诺您所做的工作

这里有两种类型的类型
static_cast
,也就是说,您告诉编译器指向基的指针是指向派生的指针,然后闭嘴继续操作
dynamic_cast
,也就是说,您要求编译器检查指向base的指针是否确实是指向派生的。您使用了
static\u cast
,因此编译器关闭并按照您所说的操作


<>编辑:约翰精确地指出,在继承层次中没有虚拟函数,你应该从C++中被激发,而<>代码> DyjiCirase> /Cord>只对虚拟函数有效。你把B作为D。因为所有编译器都知道,它在DAO上做操作。不要在C++代码中使用PrimTf。@ BatchyX:<代码> Prtuf < /C>可能是非常不安全的,但是它比 CUT和朋友要快得多。@ BATCHYX:如果正确使用,打印错误(没有错误)。尝试在一个可移植程序中混合printf和cout,看看会发生什么。printf的任何“正确用法”都不能解决这个问题。至于性能,只需启用优化,如果不刷新每个输出,printf和cout之间的差异将为零。不完全如此<除非这两种类型相关,否则代码>静态\u cast不会编译。也许您正在考虑重新解释cast@John Dibling:在某些编译时检查中,使用static cast您告诉编译器
我比您知道得更好。因此,您最好做得正确。@John Dibling:我不是说过吗?
dynamic\u cast
在这种局部情况下不起作用,因为类型不是多态的。@John:说得好。为什么人们总是发布涉及继承而没有虚拟函数的代码。知道了。愚蠢的问题。在运行时,它可能会打印内存中变量m_i所在位置的内容,如果对象位于类D上,该位置就是该变量。对吗?@DeadMG:缺少虚拟函数让我感到困惑。我认为静态强制转换涉及某种检查,不像重新解释强制转换或C强制转换。@314008:是的。你为什么这么想<代码>静态\u cast
就是这样-静态。