我有几节课,我试图了解vptr和vtable在这种情况下的工作方式。
class RGB {
short value[3];
};
class AbstractImage{
protected:
int n_pixels;
public:
virtual void show() = 0;
virtual AbstractImage* getMe() = 0;
virtual ∼AbstractImage() {};
};
template <typename T> class Image: public AbstractImage {
T* data;
public:
Image<T>(int n) { n_pixles=n; data=new T[n_pixles];}
virtual ∼Image<T>() { delete[] data; }
Image<T>(const Image<T>& rhs) {
n_pixels = rhs.n_pixels;
data = new T[n_pixels];
copyData(rhs);
}
Image<T>& operator=(const Image<T>& rhs) {
n_pixels = rhs.n_pixels;
delete[] data;
data = new T[n_pixels];
copyData(rhs);
return *this;
}
virtual void show() {/*some code*/}
virtual Image<T>* getMe() {return this;}
private:
void copyData(const Image<T>& rhs) {
for(int i=0l i<n_pixels;i++) {
data[i] = rhs.data[i];
}
}
};
typedef class Image<RGB> ColorImage;
typedef class Image<short> BWImage;
我试图找出运行以下实现后的堆栈和堆应该如何:
int main() {
AbstractImage* A = new ColorImage(4);
ColorImage B = colorImage(4);
A->show();
}
据我了解,创建了2个vptr:
它们具有相同的值(value)吗? (包含相同的地址?)
这里有几个vtable?
最佳答案
首先,重要的是要知道C++标准不了解堆栈,堆或vptr。因此,这里所说的一切都取决于实现。
我们可以从标准中得出什么?
您的代码创建2个ColorImage
对象:
A
实现相关信息
即使两个对象之一是通过指向其基类的指针访问的,这两个对象也具有相同的具体类型。
这两个对象在其内存位置中的某处可能都有一个
vptr
,指向与它们的具体(真实)类型相对应的虚拟表。大多数编译器为每种具体的类类型使用一个vptr
。因此,两个vptr
都可能指向同一虚拟表。我希望
AbstractImage
有一个虚拟表(它至少有一个虚拟函数成员),每个实例化的Image<X>
都有一个虚拟表(即,一个Image<RGB>
和一个Image<short>
的虚拟表。ColorImage
和BWImage
只是同义词。仅假设,因为只要遵守标准,编译器就可以不同地实现它。附加信息:
vptr
进行内存布局的文章。