2013-05-14 2 views
-2

Я хочу заполнить таблицу constexpr указателями для вызова указателей позже. В данном примере показана только одна запись.указатель на элемент и использование виртуальных функций

Я бегу на две проблемы:

1) Это не представляется возможным для меня, чтобы найти правильный синтаксис для записи указатель на объект члена класса, который способен инициализируется объект производного класса.

2) Я не мог использовать указатель для вызова виртуальных функций.

#include <iostream> 

using namespace std; 

class State { public: virtual void Do() const {} }; 
class S1: public State { public: virtual void Do() const { cout << "S1 Do" << endl; } }; 
class S2: public State { public: virtual void Do() const { cout << "S2 Do" << endl; } }; 

class A 
{ 
    public: 

     S1 s1; 
     S2 s2; 
}; 

class B 
{ 
    private: 
     static constexpr A a{}; 
     static constexpr State A::*state { &A::S2 }; // < do not work! 

    public: 

     void Do() const 
     { 
      (a.*state).Do(); // is it possible to have a pointer to any State class to call virtual functions? 
     } 
}; 

constexpr A B::a; 


int main() 
{ 
    B b; 
    b.Do(); 
    return 0; 
} 
+1

Есть ли какая-либо причина, почему вам нужно вложить определения типов один внутри другого (состояние, S1 и S2 внутри A)? Я думаю, это просто добавляет путаницы. –

+1

В частности, _you_ кажется запутанным определением типа/класса (его _blueprint_) и его экземплярами. Поместите определения типов и экземпляры отдельно, и ваш вопрос может начать иметь смысл. Как бы то ни было, это не так. –

+1

Этот вопрос в вашем коде, если быть более точным, показывает ваше замешательство: «возможно ли иметь указатель на любой класс состояний ...» Вы не указываете на классы. Вы указываете на объекты, т. Е. _instances_ класса. _type_ вашего указателя может быть A *, B *, State *, S1 * или S2 *, но его _value_ должно быть либо NULL, либо адресом действительного _объекта_ этого типа. Таким образом, вы не можете указывать на «любой класс состояний», на S1 (верхний регистр) или S2 (верхний регистр); вы указываете на a.s1 или a.s2, однако, с учетом «a» типа A. Книги в этом списке (http://stackoverflow.com/q/388242/96780) могут вам помочь. –

ответ

2

Я думаю, что проблема в большом стандарте. Там нет причины:

State A::*state = static_cast<State A::*>(&A::s1); 

не должен работать, но формулировка, чтобы она отсутствует в стандарте . Есть целый ряд обходных: наиболее очевидный будет иметь функцию доступа возвращающийся State* для каждого переменного члена, и использовать указатель на функцию:

class A 
{ 
public: 
    S1 s1; 
    State* getS1() { return &s1; } 
    S1 s2; 
    State* getS2() { return &s2; } 
}; 

class B 
{ 
    static A a; 
    static State* (A::*getState)(); 
public: 
    void Do() const 
    { 
     (a.*getState)()->Do(); 
    } 
} 

State* (A::* B::getState)() = &A::getS1; 
+0

Спасибо за ваш ответ! Интересно, что мой вопрос был приостановлен много раз и закрыт, пока есть ответ на него :-) – Klaus

+0

@Klaus Да. Голосование здесь странное. –