欢迎大家来信探讨:chouzhezhe@163.com
10 个解决方案
#1
jinfeng_Wang(多看一页书,少问一个问题!) :
VPTR不在VTBL中,VPTR是包含在每一个对象中,而一个类才有唯一的一个VTBL!!!
VPTR不在VTBL中,VPTR是包含在每一个对象中,而一个类才有唯一的一个VTBL!!!
#2
我是这样想的:
class base
{
...
virtual void print(){cout << "base";};
}
class derived : public base
{
...
virtual void print() { cout <<"derived";}
}
base *basePtr;
derived a;
basePtr = &a;
basePtr -> print();
过程是这样的:
basePtr = &a;//先指向a,然后复引用指针,指向derived vtable的指针开始。
basePtr->print();
// 复引用a的vtable指针,取得derived vtable
// 跳过n个字节(视成员函数个数而定),选择print()函数指针
// 复引用该函数指针,构成要执行的实际函数名,并用函数调用运算符()执行
响应的print()函数。
以上是我的理解,请指教。
class base
{
...
virtual void print(){cout << "base";};
}
class derived : public base
{
...
virtual void print() { cout <<"derived";}
}
base *basePtr;
derived a;
basePtr = &a;
basePtr -> print();
过程是这样的:
basePtr = &a;//先指向a,然后复引用指针,指向derived vtable的指针开始。
basePtr->print();
// 复引用a的vtable指针,取得derived vtable
// 跳过n个字节(视成员函数个数而定),选择print()函数指针
// 复引用该函数指针,构成要执行的实际函数名,并用函数调用运算符()执行
响应的print()函数。
以上是我的理解,请指教。
#3
我?
请大侠明示,谢谢
请大侠明示,谢谢
#4
以下列代码测试(Release故意放构造函数里的)
class A
{
public:
int i;
A(int n)
:i(n)
{
Release();
}
virtual ~A()
{
}
virtual void Release()
{
}
};
class B : public A
{
public:
int j;
B(int n)
:A(n),j(n)
{
Release();
}
virtual ~B()
{
}
virtual void Release()
{
}
};
B b(3);
结果:>
B::B(3)
A::A(3)
A::i(3)
A::__vfptr
B::j(3)
B::__vfptr
完成构造.
class A
{
public:
int i;
A(int n)
:i(n)
{
Release();
}
virtual ~A()
{
}
virtual void Release()
{
}
};
class B : public A
{
public:
int j;
B(int n)
:A(n),j(n)
{
Release();
}
virtual ~B()
{
}
virtual void Release()
{
}
};
B b(3);
结果:>
B::B(3)
A::A(3)
A::i(3)
A::__vfptr
B::j(3)
B::__vfptr
完成构造.
#5
faint! such a basic thing.
each object(with virtual function) has at least one pointer which points to the vtable.
the vtable contains function pointers of each virtual function.
got it?
why an object need a pointer to vtable?
give you a pointer to an object, tell you the interface type, do you know where is the vtable? If you know it at compile time, then it's not late binding, not virtual function at all.
"每个对象都知道它的数据类型是什么"
this is simply wrong! without a pointer to the vtable, how can it know?
class B:public A{.....};
class C:public A{.....};
void f(A* pa){}
how do you know the pa is of type A or B or C at compile time?
each object(with virtual function) has at least one pointer which points to the vtable.
the vtable contains function pointers of each virtual function.
got it?
why an object need a pointer to vtable?
give you a pointer to an object, tell you the interface type, do you know where is the vtable? If you know it at compile time, then it's not late binding, not virtual function at all.
"每个对象都知道它的数据类型是什么"
this is simply wrong! without a pointer to the vtable, how can it know?
class B:public A{.....};
class C:public A{.....};
void f(A* pa){}
how do you know the pa is of type A or B or C at compile time?
#6
jinfeng_Wang(多看一页书,少问一个问题!)
一个类包含一个VTable,VPTR是什么概念呢?
是指向虚拟函数的指针,got it?
既然是指针,那么它放在哪儿呢?VTable中!
当我们需要调用虚拟函数的时候
class *a =new A;
a->virtualfunction();
相当于对于*(VTable+i) 取得VPTR //设VTable为某个地址 ,i是该VPTR对于首地址的偏移量
然后(*VPTR)() 调用该虚拟函数
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
VTPR怎么可能会放在VTable中呢。如果一个类有虚函数,那么它明显是比没有虚函数的类多处4个字节。这4个字节给是存放VPTR。看看这个程序#include <iostream>
using namespace std;
class BaseA
{
int i;
};
class BaseB
{
public:
virtual Test();
int i;
};
class Derived: BaseB
{
int i;
};
int main()
{
cout << sizeof (BaseA) << endl;
cout << sizeof (BaseB) << endl;
cout << sizeof (Derived) << endl;
return 0;
}
一个类包含一个VTable,VPTR是什么概念呢?
是指向虚拟函数的指针,got it?
既然是指针,那么它放在哪儿呢?VTable中!
当我们需要调用虚拟函数的时候
class *a =new A;
a->virtualfunction();
相当于对于*(VTable+i) 取得VPTR //设VTable为某个地址 ,i是该VPTR对于首地址的偏移量
然后(*VPTR)() 调用该虚拟函数
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
VTPR怎么可能会放在VTable中呢。如果一个类有虚函数,那么它明显是比没有虚函数的类多处4个字节。这4个字节给是存放VPTR。看看这个程序#include <iostream>
using namespace std;
class BaseA
{
int i;
};
class BaseB
{
public:
virtual Test();
int i;
};
class Derived: BaseB
{
int i;
};
int main()
{
cout << sizeof (BaseA) << endl;
cout << sizeof (BaseB) << endl;
cout << sizeof (Derived) << endl;
return 0;
}
#7
vptr是包含在类对象里的,它指向vtable.
jinfeng_Wang(多看一页书,少问一个问题!) 的观点从根本上来讲是错的。
每个virtual function 的位置在编译时就已经确定下来,即在vtable的那一个solt中是已知的,函数的调用被转化为(*vptr[i])(this);i为已知的虚函数索引。
jinfeng_Wang(多看一页书,少问一个问题!) 的观点从根本上来讲是错的。
每个virtual function 的位置在编译时就已经确定下来,即在vtable的那一个solt中是已知的,函数的调用被转化为(*vptr[i])(this);i为已知的虚函数索引。
#8
楼主很对。
#9
我已经彻底弄明白了虚拟函数的机制了,谢谢大家的支持,可以参考《Tinking in C++》的有关章节,但是尧死亡很多的脑细胞!!!
#10
to jinfeng_Wang(多看一页书,少问一个问题!)
你的观点我有点异议,vptr是指向vtable的指针,每个对象都有一个vptr,一般是存放在对象的前几个字节中(一般是四个字节),但是每个类只有一个vtable.这一点《Inside the c++ object model》讲得很清楚。
你的观点我有点异议,vptr是指向vtable的指针,每个对象都有一个vptr,一般是存放在对象的前几个字节中(一般是四个字节),但是每个类只有一个vtable.这一点《Inside the c++ object model》讲得很清楚。
#1
jinfeng_Wang(多看一页书,少问一个问题!) :
VPTR不在VTBL中,VPTR是包含在每一个对象中,而一个类才有唯一的一个VTBL!!!
VPTR不在VTBL中,VPTR是包含在每一个对象中,而一个类才有唯一的一个VTBL!!!
#2
我是这样想的:
class base
{
...
virtual void print(){cout << "base";};
}
class derived : public base
{
...
virtual void print() { cout <<"derived";}
}
base *basePtr;
derived a;
basePtr = &a;
basePtr -> print();
过程是这样的:
basePtr = &a;//先指向a,然后复引用指针,指向derived vtable的指针开始。
basePtr->print();
// 复引用a的vtable指针,取得derived vtable
// 跳过n个字节(视成员函数个数而定),选择print()函数指针
// 复引用该函数指针,构成要执行的实际函数名,并用函数调用运算符()执行
响应的print()函数。
以上是我的理解,请指教。
class base
{
...
virtual void print(){cout << "base";};
}
class derived : public base
{
...
virtual void print() { cout <<"derived";}
}
base *basePtr;
derived a;
basePtr = &a;
basePtr -> print();
过程是这样的:
basePtr = &a;//先指向a,然后复引用指针,指向derived vtable的指针开始。
basePtr->print();
// 复引用a的vtable指针,取得derived vtable
// 跳过n个字节(视成员函数个数而定),选择print()函数指针
// 复引用该函数指针,构成要执行的实际函数名,并用函数调用运算符()执行
响应的print()函数。
以上是我的理解,请指教。
#3
我?
请大侠明示,谢谢
请大侠明示,谢谢
#4
以下列代码测试(Release故意放构造函数里的)
class A
{
public:
int i;
A(int n)
:i(n)
{
Release();
}
virtual ~A()
{
}
virtual void Release()
{
}
};
class B : public A
{
public:
int j;
B(int n)
:A(n),j(n)
{
Release();
}
virtual ~B()
{
}
virtual void Release()
{
}
};
B b(3);
结果:>
B::B(3)
A::A(3)
A::i(3)
A::__vfptr
B::j(3)
B::__vfptr
完成构造.
class A
{
public:
int i;
A(int n)
:i(n)
{
Release();
}
virtual ~A()
{
}
virtual void Release()
{
}
};
class B : public A
{
public:
int j;
B(int n)
:A(n),j(n)
{
Release();
}
virtual ~B()
{
}
virtual void Release()
{
}
};
B b(3);
结果:>
B::B(3)
A::A(3)
A::i(3)
A::__vfptr
B::j(3)
B::__vfptr
完成构造.
#5
faint! such a basic thing.
each object(with virtual function) has at least one pointer which points to the vtable.
the vtable contains function pointers of each virtual function.
got it?
why an object need a pointer to vtable?
give you a pointer to an object, tell you the interface type, do you know where is the vtable? If you know it at compile time, then it's not late binding, not virtual function at all.
"每个对象都知道它的数据类型是什么"
this is simply wrong! without a pointer to the vtable, how can it know?
class B:public A{.....};
class C:public A{.....};
void f(A* pa){}
how do you know the pa is of type A or B or C at compile time?
each object(with virtual function) has at least one pointer which points to the vtable.
the vtable contains function pointers of each virtual function.
got it?
why an object need a pointer to vtable?
give you a pointer to an object, tell you the interface type, do you know where is the vtable? If you know it at compile time, then it's not late binding, not virtual function at all.
"每个对象都知道它的数据类型是什么"
this is simply wrong! without a pointer to the vtable, how can it know?
class B:public A{.....};
class C:public A{.....};
void f(A* pa){}
how do you know the pa is of type A or B or C at compile time?
#6
jinfeng_Wang(多看一页书,少问一个问题!)
一个类包含一个VTable,VPTR是什么概念呢?
是指向虚拟函数的指针,got it?
既然是指针,那么它放在哪儿呢?VTable中!
当我们需要调用虚拟函数的时候
class *a =new A;
a->virtualfunction();
相当于对于*(VTable+i) 取得VPTR //设VTable为某个地址 ,i是该VPTR对于首地址的偏移量
然后(*VPTR)() 调用该虚拟函数
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
VTPR怎么可能会放在VTable中呢。如果一个类有虚函数,那么它明显是比没有虚函数的类多处4个字节。这4个字节给是存放VPTR。看看这个程序#include <iostream>
using namespace std;
class BaseA
{
int i;
};
class BaseB
{
public:
virtual Test();
int i;
};
class Derived: BaseB
{
int i;
};
int main()
{
cout << sizeof (BaseA) << endl;
cout << sizeof (BaseB) << endl;
cout << sizeof (Derived) << endl;
return 0;
}
一个类包含一个VTable,VPTR是什么概念呢?
是指向虚拟函数的指针,got it?
既然是指针,那么它放在哪儿呢?VTable中!
当我们需要调用虚拟函数的时候
class *a =new A;
a->virtualfunction();
相当于对于*(VTable+i) 取得VPTR //设VTable为某个地址 ,i是该VPTR对于首地址的偏移量
然后(*VPTR)() 调用该虚拟函数
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
VTPR怎么可能会放在VTable中呢。如果一个类有虚函数,那么它明显是比没有虚函数的类多处4个字节。这4个字节给是存放VPTR。看看这个程序#include <iostream>
using namespace std;
class BaseA
{
int i;
};
class BaseB
{
public:
virtual Test();
int i;
};
class Derived: BaseB
{
int i;
};
int main()
{
cout << sizeof (BaseA) << endl;
cout << sizeof (BaseB) << endl;
cout << sizeof (Derived) << endl;
return 0;
}
#7
vptr是包含在类对象里的,它指向vtable.
jinfeng_Wang(多看一页书,少问一个问题!) 的观点从根本上来讲是错的。
每个virtual function 的位置在编译时就已经确定下来,即在vtable的那一个solt中是已知的,函数的调用被转化为(*vptr[i])(this);i为已知的虚函数索引。
jinfeng_Wang(多看一页书,少问一个问题!) 的观点从根本上来讲是错的。
每个virtual function 的位置在编译时就已经确定下来,即在vtable的那一个solt中是已知的,函数的调用被转化为(*vptr[i])(this);i为已知的虚函数索引。
#8
楼主很对。
#9
我已经彻底弄明白了虚拟函数的机制了,谢谢大家的支持,可以参考《Tinking in C++》的有关章节,但是尧死亡很多的脑细胞!!!
#10
to jinfeng_Wang(多看一页书,少问一个问题!)
你的观点我有点异议,vptr是指向vtable的指针,每个对象都有一个vptr,一般是存放在对象的前几个字节中(一般是四个字节),但是每个类只有一个vtable.这一点《Inside the c++ object model》讲得很清楚。
你的观点我有点异议,vptr是指向vtable的指针,每个对象都有一个vptr,一般是存放在对象的前几个字节中(一般是四个字节),但是每个类只有一个vtable.这一点《Inside the c++ object model》讲得很清楚。