我有几个类,我试图了解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();
}根据我的理解,有两个vptr创建:
它们有相同的价值吗?(包含相同的地址?)这里有几个酒柜?
发布于 2018-03-11 11:11:46
首先,重要的是要知道C++标准不知道堆栈、堆或vptr。所以这里可以说的一切都是依赖于实现的。
,我们可以从标准中推断出什么?
您的代码创建两个ColorImage对象:
A中。实现依赖信息
这两个对象具有相同的具体类型,即使这两个对象之一是通过指向其基类的指针进行访问。
这两个对象的内存位置中可能都有指向与其具体(实)类型对应的虚拟表的vptr。大多数编译器每个具体类类型都使用一个vptr。因此,两个vptr都可能指向同一个虚拟表。
我希望为AbstractImage创建一个虚拟表(它至少有一个虚拟函数成员),为每个实例化的Image<X>提供一个虚拟表(即一个用于Image<RGB>,另一个用于Image<short>。ColorImage和BWImage只是同义词。但如上所述,这只是假设,因为只要标准得到尊重,编译器就可以以不同的方式实现它。
附加信息:
vptr进行内存布局的文章。发布于 2018-03-11 10:58:01
来自wiki:
通常,编译器为每个类创建一个单独的vtable。创建对象时,指向此vtable的指针(称为虚拟表指针、v指针或VPTR )将作为该对象的隐藏成员添加。因此,编译器还必须在每个类的构造函数中生成“隐藏”代码,以初始化指向该类vtable地址的新对象的v指针。
因此,最有可能的指针有不同的价值,但我们不能肯定地说。
https://stackoverflow.com/questions/49219090
复制相似问题