虚拟表如何存储在内存中?他们的布局?
例如
class A{
public:
virtual void doSomeWork();
};
class B : public A{
public:
virtual void doSomeWork();
};
Run Code Online (Sandbox Code Playgroud)
内存中A类和B类虚拟表的布局如何?
我知道如果一个类VTABLE包含至少一个虚函数,那么它将有一个.我想看看的内容VTABLE.有没有办法显示它?
具体来说,是否有一个选项gcc来显示VTABLE一个类?
有什么方法可以"破解"或"胁迫"协变覆盖C#?
例如:
public class Alpha {
public virtual Alpha DoSomething() {
return AlphaFactory.GetAlphaFromSomewhere();
}
}
public class Beta : Alpha {
public override Beta DoSomething() {
return BetaFactory.GetBetaFromSomewhere();
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,C#不支持这个(这看起来有点荒谬,但这既不在这里也不在那里).
我以为我可能会有方法隐藏的答案:
new public Beta DoSomething() {
return BetaFactory.GetBetaFromSomewhere();
}
Run Code Online (Sandbox Code Playgroud)
但是这并没有将条目添加到'vtable'中,它只是基本上声明了一个具有相同名称的全新方法,因此意味着Beta通过指向一个Alpha将调用的指针来访问s Alpha.DoSomething().
那么,有什么好的伎俩吗?
我最近在接受采访时询问了有关虚拟功能和多重继承的对象布局.
我在没有涉及多重继承的情况下如何实现它的上下文中解释了它(即编译器如何生成虚拟表,在每个对象中插入指向虚拟表的秘密指针等等).
在我看来,我的解释中缺少一些东西.
所以这里有问题(见下面的例子)
示例代码:
class A {
public:
virtual int funA();
private:
int a;
};
class B {
public:
virtual int funB();
private:
int b;
};
class C : public A, public B {
private:
int c;
};
Run Code Online (Sandbox Code Playgroud)
谢谢!
c++ multiple-inheritance virtual-inheritance vtable memory-layout
我正在调试一个崩溃日志.发生崩溃是因为(c ++ - )对象的vtable指针是0x1,而对象的其余部分似乎可以从崩溃日志中看出来.
程序在尝试调用虚方法时崩溃.
我的问题:在什么情况下vtable指针变为空?operator delete是否将vtable指针设置为null?
这在OS X上使用gcc 4.0.1(Apple Inc. build 5493)发生.
我最近正在接受采访,其中C/C++是主要语言,在一个问题中,我被告知可以使用vtable来确定基本指针实际存储的层次结构中的哪个类.
所以,如果,例如,你有
class A
{
public:
A() {}
virtual ~A() {}
virtual void method1() {}
};
class B : public A
{
public:
B() {}
virtual ~B() {}
virtual void method1() {}
};
Run Code Online (Sandbox Code Playgroud)
并且您实例化A * pFoo = new B(),是否确实可以使用vtable来确定pFoo是否包含指向A或B实例的指针?
例如,我有两个"接口"和类类型:
class IPlugin
{
public:
virtual void Load(void) = 0;
virtual void Free(void) = 0;
};
class IFoo
{
public:
virtual void Foo(void) = 0;
};
class Tester: public IPlugin, public IFoo
{
public:
Tester() {};
~Tester() {};
virtual void Load()
{
// Some code here
}
virtual void Free()
{
// Some code here
}
virtual void Foo(void)
{
// Some code here
}
};
Run Code Online (Sandbox Code Playgroud)
vtab实际上具有哪种结构类型Tester?而如何将 dynamic_cast运营商的行为(我的意思是如何dynamic_cast操作员将扫描vtab为有效的引用类型皈依)的表达式:
Tester* t = new Tester();
IPlugin* plg …Run Code Online (Sandbox Code Playgroud) 我希望在C中实现动态调度的提示(最好通过一个很好的例子).
我正在学习C并且作为练习,我想使用动态调度虚拟方法表从Java转换为C.
例如我有一个java代码:
abstract class Foo {
public abstract int val();
public abstract Boolean error();
}
class Fail extends Foo {
public int val(){ return 0;}
public Boolean error(){return true;}
}
class IntFoo extends Foo {
int v;
public IntFoo(int value){this.value=v;}
public int val(){ return v;}
public Boolean error(){return False;}
}
Run Code Online (Sandbox Code Playgroud)
我可以翻译一些像这样的基本内容:
typedef struct Foo{
void(**vtable);
}Foo;
typedef struct Fail{
void(**vtable);
struct Foo inherited;
}Fail;
typedef struct IntFoo{
void(**vtable);
struct Foo inherited;
}IntFoo;
Run Code Online (Sandbox Code Playgroud)
我在试图完成这个时遇到困难,因为我不知道:
vtable以便编译器识别正确的调用方法.假设我们在父类和派生类中有多个虚函数.对于父派生类,将在vtable中为这些虚函数创建一个vtable.
编译器如何知道vtable中的哪个条目对应于哪个虚函数?
例:
class Animal{
public:
void fakeMethod1(){}
virtual void getWeight(){}
void fakeMethod2(){}
virtual void getHeight(){}
virtual void getType(){}
};
class Tiger:public Animal{
public:
void fakeMethod3(){}
virtual void getWeight(){}
void fakeMethod4(){}
virtual void getHeight(){}
virtual void getType(){}
};
main(){
Animal a* = new Tiger();
a->getHeight(); // A will now point to the base address of vtable Tiger
//How will the compiler know which entry in the vtable corresponds to the function getHeight()?
}
Run Code Online (Sandbox Code Playgroud)
我的研究中没有找到确切的解释 -
"该表用于解析函数调用,因为它包含该类的所有虚函数的地址."
该表用于解析函数调用的具体方式是什么?
我可以理解为什么dynamic_cast在这种情况下有效:
#include <iostream>
struct A{
virtual ~A() = default;
};
struct B {
virtual ~B() = default;
};
struct C : A, B{};
void f(const A &a) {
if(auto p = dynamic_cast<const B*>(&a))
std::cout << "a is a B" << std::endl;
}
int main() {
f(C{});
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是为什么如果你从B中删除多态,它仍然有效:
#include <iostream>
struct A{
virtual ~A() = default;
};
struct B {
};
struct C : A, B{};
void f(const A &a) {
if(auto p = dynamic_cast<const B*>(&a))
std::cout << …Run Code Online (Sandbox Code Playgroud) vtable ×10
c++ ×8
gcc ×2
c ×1
c# ×1
covariance ×1
crash ×1
dynamic-cast ×1
java ×1
macos ×1
methods ×1
polymorphism ×1
vptr ×1