本文介绍了成员转换指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



4.11 / 2指向成员转换的指​​针

strong>

5.2.9 / 9 static_cast

这里是我的问题。如5.2.9 / 9所述,如果存在4.11 / 2中描述的有效转换,则指向D的成员的指针可以转换为指向B的成员的指针。这是否意味着如果有一个D的成员m不是从B继承的,那么指向成员m的指针不能转换成指向B成员的指针类型?

  class Base {}; 
class Derived:public Base
{
int a;
};
typedef int Base :: * BaseMemPtr;
BaseMemPtr pa = static_cast< BaseMemPtr>(& Derived :: a); // invalid,as per 5.2.9 / 9?

在5.2.9 / 9的注释中,它还说,虽然类B不需要包含原始成员,取消引用成员的指针的对象的动态类型必须包含原始成员。



我对该段落的措辞感到困惑。上面的代码是否有效?



我搜索了该网站,还有一个类似的问题,,其答案仅涵盖从指针到基类的成员转换为指向派生类的成员的指针的情况。

解决方案

您写的代码是完全有效的。没有什么问题(除了 Derived :: a 是私有的)的事实。它是良好形式和行为被定义(到目前为止)。正如标准的引用部分所说,使用显式的 static_cast ,upcast成员指针是完全合法的,这正是你在做什么。 5.2.9 / 9从来没有说尖端的成员必须出现在基类中。



另外,正如你从标准中引用的,在指针的取消引用时需要在对象中的成员,而不是在初始化时。这当然取决于在成员访问运算符( - > * 的左侧使用的对象的动态类型) 。* )。该类型只在运行时才知道,因此不能由编译器检查。



此要求仅作为注释包含在5.2.9 / 9中,但在5.5 / 4中以更正式的形式重复。

例如,在您的示例的上下文中,以下代码行格式良好

  Base b; 
b。* pa; // 1

派生d;
d。* pa; // 2

Base * pb =& d;
pb-> * pa; // 3

但是,第一个取消引用会产生未定义的行为(因为对象 b 不包含成员),而第二个和第三个是完全合法的。


I just found the following paragraphs in c++03 standard draft relevant to pointer to member conversion.

4.11/2 Pointer to member conversions

5.2.9/9 static_cast

So here's my question. As 5.2.9/9 says, a pointer to member of D can be converted to a pointer to member of B, if there's a valid conversion described in 4.11/2 exists. Do this mean that if there's a member 'm' of D which is not inherited from B, the pointer to member 'm' cannot be casted to the type of pointer to member of B?

class Base { };
class Derived : public Base 
{
    int a;
};
typedef int Base::* BaseMemPtr;
BaseMemPtr pa = static_cast<BaseMemPtr>(&Derived::a); // invalid, as per 5.2.9/9 ?

In the note of 5.2.9/9, it also says that although class B need not contain the original member, the dynamic type of the object on which the pointer to member is dereferenced must contain the original member.

I get confused with the wording of the paragraph. Is the code above valid ?

I searched the site, and there's a similar question, c++ inheritance and member function pointers, whose answer only covered the case that conversion from pointer to member of base class to pointer to member of derived class.

解决方案

The code you wrote is perfectly valid. There's nothing wrong with it (aside from the fact that Derived::a is private). It is well-formed and the behavior is defined (so far). As the quoted portion of the standard says, it is perfectly legal to upcast member pointers using an explicit static_cast, which is exactly what you are doing. 5.2.9/9 never says that the pointed member has to be present in the base class.

Also, as you correctly quoted from the standard, the presence of the actual member in the object is required later at the moment of dereference of the pointer, not at the moment of initialization. This, of course, depends on the dynamic type of the object used at the left-hand side of member-access operator (->* or .*). The type is only known at run-time and thus cannot be checked by the compiler.

This requirement is included as a mere note into 5.2.9/9, but it is reiterated in a more formal form in 5.5/4

So, for example, in the context of your example the following lines of code are well-formed

Base b;
b.*pa; // 1

Derived d;
d.*pa; // 2

Base *pb = &d;
pb->*pa; // 3

However, the first dereference produces undefined behavior (since object b does not contain the member), while both the second one and the third one are perfectly legal.

这篇关于成员转换指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-02 11:59