最近,我遇到了几个使用"手动"vtable的类型擦除实现 - Adobe ASLany_regular_t就是一个例子,虽然我已经看到它也用在Boost ASIO中(用于完成例程队列).
基本上,父类型传递一个指向静态类型的指针,该类型充满了在子类型中定义的函数指针,类似于下面的...
struct parent_t;
struct vtbl {
void (*invoke)(parent_t *, std::ostream &);
};
struct parent_t {
vtbl *vt;
parent_t(vtbl *v) : vt(v) { }
void invoke(std::ostream &os) {
vt->invoke(this, os);
}
};
template<typename T>
struct child_t : parent_t {
child_t(T val) : parent_t(&vt_), value_(val) { }
void invoke(std::ostream &os) {
// Actual implementation here
...
}
private:
static void invoke_impl(parent_t *p, std::ostream &os) {
static_cast<child_t *>(p)->invoke(os);
}
T value_;
static vtbl vt_;
};
template<typename …Run Code Online (Sandbox Code Playgroud) 哪个虚拟表将是纯虚函数?在基类或派生类中?
例如,每个类中的虚拟表是什么样的?
class Base {
virtual void f() =0;
virtual void g();
}
class Derived: public Base{
virtual void f();
virtual void g();
}
Run Code Online (Sandbox Code Playgroud) Vtables在大多数OO实现中无处不在,但他们有替代方案吗?vtables的wiki页面有一个简短的模糊,但不是真正的太多信息(和存根链接).
你知道一些不使用vtables的语言实现吗?
是否有免费的在线页面讨论替代方案?
我知道对于任何具有虚函数的类或者从具有虚函数的类派生的类,编译器会做两件事.首先,它为该类创建一个虚拟表,然后,它将虚拟指针(vptr)放在该对象的基础部分中.在运行时,此vptr被分配并在对象实例化时开始指向正确的vtable.
我的问题是,在实例化过程中,这个vptr的确切位置是什么?这个vptr的赋值是否发生在构造函数之前/之后的对象的构造函数中?
可以使用该__declspec(novtable)属性在MSVC中完成抑制C++ vtable生成.但是,似乎GNU C++编译器没有等效属性.事实上,将vtable留给纯虚拟类不必要地链接到__cxa_abort()许多其他类,我想避免这种情况发生,因为我正在为嵌入式系统编程.所以我该怎么做?
struct ISomeInterface
{
virtual void Func() = 0;
};
class CSomeClass : public ISomeInterface
{
virtual void Func();
}
void CSomeClass::Func()
{
//...
}
Run Code Online (Sandbox Code Playgroud) 我知道如果一个类VTABLE包含至少一个虚函数,那么它将有一个.我想看看的内容VTABLE.有没有办法显示它?
具体来说,是否有一个选项gcc来显示VTABLE一个类?
vtable包含指向该类的虚函数的指针.它是否也包含指向非虚函数的指针?
谢谢!
我有很难去骗取下班的大小是什么?
我正在使用MSVS 2008(VC 9.0编译器).我已经读过,如果我没有声明虚函数(在下面的例子中),那么D类将包含2个额外的指针(来自B的1和来自C的另一个),它将指向A的共享实例.
但是在下面的情况下,每个类的内存映射是什么(也有虚函数)?
class A
{
public:
int a;
virtual void Func();
public:
A(void);
~A(void);
};
class B :virtual public A
{
public:
int b;
virtual void Func();
public:
B(void);
~B(void);
};
class C: virtual public A
{
public:
int c;
virtual void Func();
public:
C(void);
~C(void);
};
class D : public B, public C
{
public:
int d;
virtual void Func();
public:
D(void);
~D(void);
};
int _tmain(int argc, _TCHAR* argv[])
{
cout << "size of Class A …Run Code Online (Sandbox Code Playgroud) c++ virtual-functions virtual-inheritance vtable diamond-problem
有什么方法可以"破解"或"胁迫"协变覆盖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().
那么,有什么好的伎俩吗?
我读了一个问题:C ++虚拟类继承对象大小问题,并且想知道为什么虚拟继承会在类中导致附加的vtable指针。
我在这里找到了一篇文章:https : //en.wikipedia.org/wiki/Virtual_inheritance
告诉我们:
但是,通常只能在运行时知道此偏移量,...
我在这里不了解与运行时相关的内容。完整的类继承层次结构在编译时就已经知道。我了解虚函数和基指针的用法,但是虚继承没有这种东西。
有人可以解释为什么某些编译器(Clang / GCC)使用vtable实现虚拟继承以及在运行时如何使用它吗?
顺便说一句,我也看到了这个问题:在虚拟继承的情况下使用vtable,但是它仅指向与虚拟函数相关的答案,这不是我的问题。
vtable ×10
c++ ×8
gcc ×2
methods ×2
virtual ×2
vptr ×2
c# ×1
constructor ×1
covariance ×1
g++ ×1
type-erasure ×1