C++ 计算vptr字段

C++ 计算vptr字段,c++,inheritance,polymorphism,vptr,virtual-table,C++,Inheritance,Polymorphism,Vptr,Virtual Table,我有几节课,我试图了解vptr和vtable在这种情况下是如何工作的 class RGB { short value[3]; }; class AbstractImage{ protected: int n_pixels; public: virtual void show() = 0; virtual AbstractImage* getMe() = 0; virtual ∼AbstractImage() {};

我有几节课,我试图了解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;
据我所知,创建了两个vptr:

  • B::vpointer-在堆栈上
  • A::vpointer-在堆上
  • 它们有相同的值吗?(是否包含相同的地址?) 这里有多少vtables?

    来自wiki:

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


    <> Pv>大多数VoPosits都有不同的值,但我们不能肯定。

    首先,重要的是要知道C++标准不知道堆栈、堆和VPTR。因此,这里可以说的一切都取决于实现

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

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

    • 免费存储中的一个对象,具有动态存储持续时间(在您的术语中称为“heap”),并且哪个指针存储在
      A
    • 自动持续时间的本地对象(术语中称为“堆栈”)
    • 这是两个不同的物体
    实施相关信息

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

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

    我希望
    AbstractImage
    有一个虚拟表(它至少有一个虚拟函数成员),每个实例化的
    Image
    (也就是说,
    Image
    Image
    ColorImage
    BWImage
    只是同义词。但正如所说,这只是假设,因为只要遵守标准,编译器就可以以不同的方式实现它

    其他信息:

    • :关于单一继承情况下的vptr和vptr布局的文章
    • :关于单继承和多继承情况下使用
      vptr
      的内存布局的文章

    这是你正在使用的特定C++实现的实现细节。你从来没有告诉我们,你使用的是哪个编译器,所以没有答案是现成的。你需要查阅C++实现的文档,并且你应该明确地使用你的调试器来了解更多的内部工作。这是标准化的。当我开车时,我不太关心制造商如何安排发动机罩下的东西(美国佬的发动机罩)。为什么这对你来说很重要?我你将试图摆弄机制代码是a)不是b)可以在更高版本的编译器上中断(c)代码是不可维护的。问题是,这是一次考试的一部分,他们问vptr是否确实包含相同的地址,如果有可能,他们不包含相同的地址-我可以上诉。@AdamMorad-如果是在考试中-这是一个不公平的问题。这取决于编译器的制造商。只要它符合标准,那么它依赖于编译器?是否有一个编译器会导致虚拟指针指向不同的地址?@AdamMorad据我所知并不多,因为vptr通常也用于存储指向类型信息的指针(例如:)。但是您应该避免在代码中依赖任何关于vptr的假设。@AdamMorad-它可能不是传统意义上的指针-可能是vtable数组的索引。谁知道呢?只要编译器遵守标准,他们就可以实现多种可能性。问题是,这是一次考试的一部分,他们问vptr是否确实包含相同的地址,如果有可能不包含,我可以在分数上上诉。
    int main() {
        AbstractImage* A = new ColorImage(4);
        ColorImage B = colorImage(4);
        A->show();
    }