根据我对C++规范的了解(有限),具有虚拟成员的类的vtable被放置在第一个非纯非内联虚拟方法的定义中.编译器如何处理从具有ALL纯虚方法(例如接口)的类继承的类?在这种情况下,vtable放在哪里?
我无法弄清楚这里发生了什么,认为这是非常奇怪的,并且在了解了我之后认为分享答案的原因对于某个人的时间是有价值的.
所以给出这个简单的代码:
#include <iostream>
using namespace std;
class Shape {
public:
int* a;
Shape(){
cout<<"Default Shape constructor"<<endl;
a = new int(8); // default
}
Shape(int n){
a = new int(n);
cout<<"Shape(n) constructor"<<endl;
}
// copy constructor
Shape(const Shape& s){
cout<<"Shape copy constructor"<<endl;
a = new int(*(s.a));
}
Shape& operator=(const Shape& s){
cout<<"Shape operator="<<endl;
if (&s == (this))
return (*this);
// this.clear();
a = new int(*(s.a));
return (*this);
}
virtual void draw(){
cout<<"Print Shape the number is "<<*a<<endl;
};
virtual ~Shape(){ …Run Code Online (Sandbox Code Playgroud) 我最近在bitsquid博客上阅读了一篇关于如何管理内存的文章,作者开始讨论vtable以及编译器如何将类添加到类中.这是该文章的链接.因为我几乎不知道关于这个问题的事情,所以我开始在网上寻找解释.我来到了这个链接.根据我读到的内容,我制作了以下代码:
char cache[24];
printf("Size of int = %d\n", sizeof(int));
printf("Size of A = %d\n", sizeof(A));
A* a = new(cache)A(0,0);
printf("%s\n",cache);
printf("vTable : %d\n",*((int*)cache));
printf("cache addr: %d\n",&cache);
int* funcPointer = (int*)(*((int*)cache));
printf("A::sayHello: %d\n",&A::sayHello);
printf("funcPointer: %d\n",*funcPointer);
Run Code Online (Sandbox Code Playgroud)
A是一个具有两个整数成员和一个虚函数的类sayHello().
编辑:这是类定义:
class A {
public:
int _x;
int _y;
public:
A(int x, int y) : _x(x), _y(y){ }
virtual void sayHello() { printf("Hello You!"); }
};
Run Code Online (Sandbox Code Playgroud)
基本上我试图做的是看看vtable中的指针是否指向与我所从的地址相同的位置&A::sayHello,但问题是当我运行程序时,vtable中指针内的地址和sayHello()地址总是有区别的295.有谁知道为什么会发生这种情况?是否有某种标题被添加,我错过了?我在64位机器上运行visual studio express 2008.
从我调试的地址返回的 …
我写了这个非常简单的C++程序,我想知道为什么编译器会在两个指针引用之间列出vtable.这是C++程序:
class Foo {
public:
virtual void bar() {
}
};
int main(int argc, char *arv[]) {
Foo foo;
Foo *foo_p(&foo);
foo_p->bar();
}
Run Code Online (Sandbox Code Playgroud)
现在,我可以看一下编译器生成的程序集:
$ g++ -ggdb -Wall -O0 -S test.cpp
Run Code Online (Sandbox Code Playgroud)
以下是相关部分:
.loc 1 9 0
leaq -16(%rbp), %rax # put the address of 'foo' in %rax
movq %rax, %rdi # use it as the first argument of the following function
call _ZN3FooC1Ev # call the Foo constructor
.loc 1 10 0
leaq -16(%rbp), %rax # put the address of …Run Code Online (Sandbox Code Playgroud) 我对虚拟析构函数和虚函数表有一些具体问题。
假设我有以下代码:
class Base
{
public:
virtual ~Base();
};
class Child : public Base
{
public:
~Child();
};
Run Code Online (Sandbox Code Playgroud)
问题:
假设有这样一个抽象类:
class Base {
public:
virtual void f() = 0;
virtual ~Base() = default;
};
Run Code Online (Sandbox Code Playgroud)
还有一些功能:
void function (Base& x, bool flag1, bool flag2, bool flag3) {
if(flag1)
x.f();
if(flag2)
x.f();
if(flag3)
x.f();
}
Run Code Online (Sandbox Code Playgroud)
在main()函数中,我从共享库加载派生自该类的实例:
int main() {
Base* x = /* load from shared lib*/;
bool flag1 = getchar() == '1';
bool flag2 = getchar() == '2';
bool flag3 = getchar() == '3';
function(*x, flag1, flag2, flag3);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
问题:我是否可以期望在一次函数调用中,void function (Base& x, bool flag1, …
虽然 C++ 标准将虚拟调度的实现留给了编译器,但目前只有 3 个主要编译器(gcc、clang 和 msvc)。
当您通过指向抽象基类的指针调用抽象基类上的方法时,它们如何实现虚拟调度?构建期间如何设置 vtable?
一个简单的“好像”示例会很有用。
c++ polymorphism language-implementation vtable dynamic-dispatch
试图制作一个Fraps类型的程序.查看评论失败的位置.
#include "precompiled.h"
typedef IDirect3D9* (STDMETHODCALLTYPE* Direct3DCreate9_t)(UINT SDKVersion);
Direct3DCreate9_t RealDirect3DCreate9 = NULL;
typedef HRESULT (STDMETHODCALLTYPE* CreateDevice_t)(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow,
DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters,
IDirect3DDevice9** ppReturnedDeviceInterface);
CreateDevice_t RealD3D9CreateDevice = NULL;
HRESULT STDMETHODCALLTYPE HookedD3D9CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow,
DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters,
IDirect3DDevice9** ppReturnedDeviceInterface)
{
// this call makes it jump to HookedDirect3DCreate9 and crashes. i'm doing something wrong
HRESULT ret = RealD3D9CreateDevice(Adapter, DeviceType, hFocusWindow, BehaviorFlags,
pPresentationParameters, ppReturnedDeviceInterface);
return ret;
}
IDirect3D9* STDMETHODCALLTYPE HookedDirect3DCreate9(UINT SDKVersion)
{
MessageBox(0, L"Creating d3d", …Run Code Online (Sandbox Code Playgroud) 每个类都有C++中的虚函数表吗?
我知道虚拟表是为了多态.具有虚函数的类必须具有v-table.但是类没有虚函数呢?或者类没有基类怎么样?
我开始研究CRTP习语,我注意到GCC有一个fdevirtualize标志,应该允许在可能的vtable调用直接调用时进行转换.
虽然CRTP可以应用于任何(C++兼容)编译器,但如果我只想用gcc开发,我可以避免CRTP习惯用于将gcc作为虚拟化过程,或者在使用静态多态性时最好使用它.为了避免虚函数调用?