非多态继承是否发生指针调整? [英] Does this pointer adjustment occur for non-polymorphic inheritance?

查看:89
本文介绍了非多态继承是否发生指针调整?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

非多态继承是否需要此指针调整?在所有情况下,我都看到此指针调整讨论了通过关键字virtual使用涉及多态继承的示例.

Does non-polymorphic inheritance require this pointer adjustment? In all the cases I've seen this pointer adjustment discussed the examples used involved polymorphic inheritance via keyword virtual.

我尚不清楚非多态继承是否需要此指针调整.

It's not clear to me if non-polymorphic inheritance would require this pointer adjustment.

一个非常简单的例子是:

An extremely simple example would be:

struct Base1 {
    void b1() {}
};

struct Base2 {
    void b2() {}
};

struct Derived : public Base1, Base2 {
    void derived() {}
};

以下函数调用是否需要调整指针?

Would the following function call require this pointer adjustment?

Derived d;
d.b2();

在这种情况下,此指针调整显然是多余的,因为没有数据成员被访问.另一方面,如果继承的函数访问了数据成员,则此指针调整可能是一个好主意.另一方面,如果未内联成员函数,则无论如何都需要进行指针调整.

In this case the this pointer adjustment would clearly be superfluous since no data members are accessed. On the other hand, if the inherited functions accessed data members then this pointer adjustment might be a good idea. On the other other hand, if the member functions are not inlined it seems like this pointer adjustment is necessary no matter what.

我意识到这是一个实现细节,而不是C ++标准的一部分,但这是一个有关实际编译器行为的问题.我不知道这是不是像vtables这样的情况,其中所有编译器都遵循相同的一般策略,或者我是否问过一个非常依赖编译器的问题.如果它完全依赖于编译器,那么它本身就足够了;如果您愿意,也可以专注于gcc或clang.

I realize this is an implementation detail and not part of the C++ standard but this is a question about how real compilers behave. I don't know if this is a case like vtables where all compilers follow the same general strategy or if I've asked a very compiler dependent question. If it is very compiler dependent, then that in itself would be a sufficient answer or if you'd prefer, you can focus on either gcc or clang.

推荐答案

语言未指定对象的布局.根据C ++草案标准N3337:

Layout of objects is not specified by the language. From the C++ Draft Standard N3337:

10个派生类

5未指定在最派生对象(1.8)中分配基类子对象的顺序. [注意:派生类及其基类的子对象可以用有向无环图(DAG)表示,其中箭头表示直接派生自".子对象的DAG通常称为子对象晶格".

5 The order in which the base class subobjects are allocated in the most derived object (1.8) is unspecified. [ Note: a derived class and its base class subobjects can be represented by a directed acyclic graph (DAG) where an arrow means "directly derived from." A DAG of subobjects is often referred to as a "subobject lattice."

6箭头不必在内存中具有物理表示. —尾注]

6 The arrows need not have a physical representation in memory. —end note ]

出现您的问题:

以下函数调用是否需要调整指针?

Would the following function call require this pointer adjustment?

这取决于编译器如何创建对象布局.可能会也可能不会.

It depends on how the object layout is created by the compiler. It may or may not.

在您的情况下,由于类中没有成员数据,因此没有虚拟成员函数,并且您正在使用第一个基类的成员函数,因此可能看不到任何指针调整.但是,如果添加成员数据并使用第二个基类的成员函数,则很可能会看到指针调整.

In your case, since there are no member data in the classes, there are no virtual member functions, and you are using the member function of the first base class, you probably won't see any pointer adjustments. However, if you add member data, and use a member function of the second base class, you are most likely going to see pointer adjustments.

这是一些示例代码以及运行该代码的输出:

Here's some example code and the output from running the code:

#include <iostream>

struct Base1 {
   void b1()
   {
      std::cout << (void*)this << std::endl;
   }
   int x;
};

struct Base2 {
   void b2()
   {
      std::cout << (void*)this << std::endl;
   }
   int y;
};

struct Derived : public Base1, public Base2 {
   void derived() {}
};

int main()
{
   Derived d;
   d.b1();
   d.b2();
   return 0;
}

输出:


0x28ac28
0x28ac2c

这篇关于非多态继承是否发生指针调整?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆