从'Derived X :: *'到'Base X :: *'的指针到成员无效转换

时间:2016-01-04 18:48:28

标签: c++ pointers pointer-to-member

我想知道为什么在指向成员转换的情况下,从派生类指针到基类指针的简单转换会失败。例如,

    struct Base {};
    struct Derived: public Base {};

    struct X {
      Derived field;
    };

    int main(int argc, char *argv[]) {
      Base X::* ptr1 = &X::field;
      return 0;
    }

给出错误:

$ g++ t.cc
t.cc: In function ‘int main(int, char**)’:
t.cc:9:24: error: invalid conversion from ‘Derived X::*’ to ‘Base X::*’ [-fpermissive]
   Base X::* ptr1 = &X::field;
                        ^

3 个答案:

答案 0 :(得分:3)

因为两者之间没有有意义的转换。

您正在尝试为B类"中的事物分配一个"指针。到类型为&#34的对象;指向A类"中的事物的指针。

这两个类之间的继承关系在这里并不相关 - A类根本不包含你想要指向的东西。类型系统正在发挥作用。

您必须找到一些其他方式来做您正在尝试做的事情。不幸的是你没有说出那是什么,所以我无法继续帮助!

答案 1 :(得分:1)

这是对的。使用指向成员的指针时,不能使用指向base的指针来标识派生类。指向成员的指针不是指针! :)

答案 2 :(得分:-1)

Base X::*

表示指向具有Base类型的X成员的指针。

不一样
Base*

没有转换
Base*

Base X::*  

因此无法从

转换
Derived*

Base X::*  

同样,Base X::*Derived X::*

之间没有转化

示例:

#include <iostream>
using namespace std;

class Base
{
};

class Derived : public Base
{
};

class X {
public:
    Derived field1;
    Base field2;
};


int main() {
  Base X::* ptr1 = &X::field1;     // Derived X::* to Base X::* OK ?
  Derived X::* ptr2 = &X::field2;  // Base X::* to Derived X::* OK ?  

  return 0;
}

这将导致

prog.cpp:20:28: error: invalid conversion from 'Derived X::*' to 'Base X::*' [-fpermissive]
       Base X::* ptr1 = &X::field1;  
                            ^
prog.cpp:21:31: error: invalid conversion from 'Base X::*' to 'Derived X::*' [-fpermissive]
       Derived X::* ptr2 = &X::field2;  

因此,为了编译,需要:

int main() {
  Derived X::* ptr1 = &X::field1;  
  Base X::* ptr2 = &X::field2;  

  return 0;
}

下面是如何使用指针成员的示例:

#include <iostream>
#include <vector>
using namespace std;

class Base
{
    public:
    Base(int g1) : g(g1) {}
    int g;
};

class Derived : public Base
{
    public:
    Derived(int d) : Base(d) {}
};

class X {
public:
    X(int f1, int f2) : field1(f1), field2(f2) {}
    Derived field1;
    Derived field2;
};

void foo(vector<X>& vx, Derived X::*d)
{
    cout << "foo" << endl;
    for (auto& x : vx)
    {
        cout << (x.*d).g << endl;
    }
}

int main() {
  vector<X> vx {{5, 10}, {50, 100}};
  foo(vx, &X::field1);  // Print field1.g of all elements in vector vx
  foo(vx, &X::field2);  // Print field2.g of all elements in vector vx

  return 0;
}

这将输出:

foo
5
50
foo
10
100