首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >计算vptr字段

计算vptr字段
EN

Stack Overflow用户
提问于 2018-03-11 10:42:12
回答 2查看 330关注 0票数 2

我有几个类,我试图了解vptr和vtable在这种情况下是如何工作的。

代码语言:javascript
复制
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;

在运行以下实现之后,我试图弄清楚堆栈和堆应该是怎样的:

代码语言:javascript
复制
int main() {
    AbstractImage* A = new ColorImage(4);
    ColorImage B = colorImage(4);
    A->show();
}

根据我的理解,有两个vptr创建:

  1. B::v指针-在堆栈上
  2. ::v指针-在堆上

它们有相同的价值吗?(包含相同的地址?)这里有几个酒柜?

EN

回答 2

Stack Overflow用户

发布于 2018-03-11 11:11:46

首先,重要的是要知道C++标准不知道堆栈、堆或vptr。所以这里可以说的一切都是依赖于实现的。

,我们可以从标准中推断出什么?

您的代码创建两个ColorImage对象:

  • 空闲存储中的一个对象,具有动态存储时间(术语中称为“堆”),以及哪个指针存储在A中。
  • 自动持续时间的本地对象(术语中的“堆栈”)
  • 是两个不同的物体

实现依赖信息

这两个对象具有相同的具体类型,即使这两个对象之一是通过指向其基类的指针进行访问。

这两个对象的内存位置中可能都有指向与其具体(实)类型对应的虚拟表的vptr。大多数编译器每个具体类类型都使用一个vptr。因此,两个vptr都可能指向同一个虚拟表。

我希望为AbstractImage创建一个虚拟表(它至少有一个虚拟函数成员),为每个实例化的Image<X>提供一个虚拟表(即一个用于Image<RGB>,另一个用于Image<short>ColorImageBWImage只是同义词。但如上所述,这只是假设,因为只要标准得到尊重,编译器就可以以不同的方式实现它。

附加信息:

  • 多态对象的存储布局:关于单继承情况下vptr和vptr布局的文章
  • 被认为有用的多重继承:关于在单继承和多继承情况下使用vptr进行内存布局的文章。
票数 1
EN

Stack Overflow用户

发布于 2018-03-11 10:58:01

来自wiki:

通常,编译器为每个类创建一个单独的vtable。创建对象时,指向此vtable的指针(称为虚拟表指针、v指针或VPTR )将作为该对象的隐藏成员添加。因此,编译器还必须在每个类的构造函数中生成“隐藏”代码,以初始化指向该类vtable地址的新对象的v指针。

因此,最有可能的指针有不同的价值,但我们不能肯定地说。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49219090

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档