1

我正在尝试以多态方式使用指向成员变量的指针。

这有效:

struct Foo
{
   int member0;
   int member1;

   int* getMember( int i )
   {
     static int Foo::* table[2] = { &Foo::member0, &Foo::member1 };
     return &( this->*table[i] );
   }
};

这不是,因为成员不是同一类型(BaseClass):

struct Foo
{
   SubClassA member0;
   SubClassB member1;

   BaseClass* getMember( int i )
   {
     static BaseClass Foo::* table[2] = { &Foo::member0, &Foo::member1 };
     return &( this->*table[i] );
   }
};

g++报错是:

[...] invalid conversion from 'SubClassA Foo::*' to 'BaseClass Foo::*'
[...] invalid conversion from 'SubClassB Foo::*' to 'BaseClass Foo::*'

有没有办法使这项工作,即将成员指针“向上转换”到它的基类?

4

3 回答 3

1
BaseClass* getMember(const int i)
{
  switch(i)
  {
  case 0: return &member0;
  case 1: return &member1;
  default: throw <exception>;
  }
}

为了稳健性,无论如何您都必须检查 是否在i范围内或 0 和 1 内;所以你可以考虑这种简化的方法。

于 2011-08-16T16:39:36.150 回答
1

这是不可能的。由于多重继承,基地址并不总是与派生地址相同。您需要一些隐藏的地址调整魔术来将一个转换为另一个,而指向成员的指针作为一个非常简单的对象(基本上是整数偏移量)无法适应这种魔术。

确实,有时只需要调整地址,当不需要时,原则上可以允许多态成员指针。但为了简单和一致,这并没有完成。

您可以使用指向接受 Foo* 并返回 BaseClass* 的函数(或类似函数的对象)的指针,而不是指向成员的指针。但是,您必须为每个成员创建一个单独的函数。

于 2011-08-16T19:20:28.553 回答
0

更简单的方法是完全跳过成员数据指针。

getMember(int i) {
    BaseClass* ptr[2] = { &member0, &member1 };
    return ptr[i];
}
于 2011-08-16T16:29:31.970 回答