Альтернатива статическим виртуальным методам c ++ - PullRequest
36 голосов
/ 27 апреля 2010

В C ++ невозможно объявить статическую виртуальную функцию, также не приведите нестатическую функцию к указателю функции в стиле C.

Теперь у меня есть простой старый SDK C, который интенсивно использует указатели на функции,

Я должен заполнить структуру несколькими указателями на функции.Я планировал использовать абстрактный класс с кучей статических чисто виртуальных методов, переопределить их в производных классах и заполнить ими структуру.Только тогда я понял, что статические виртуальные недопустимы в C ++.

Также эта сигнатура функции C SDK не имеет параметра userData.

Есть ли хорошая альтернатива?Лучшее, что я могу придумать, - это определить некоторые чисто виртуальные методы GetFuncA (), GetFuncB (), ... и некоторые статические члены FuncA () / FuncB () в каждом производном классе, которые будут возвращены GetFuncX ().Тогда функция в абстрактном классе будет вызывать эти функции, чтобы получить указатели и заполнить структуру.

Редактировать Отвечая Джону Диблингу, было бы здорово сделать это:

class Base
{
    FillPointers() { myStruct.funA = myFunA; myStruct.funB = myFunB; ...}
private:
    CStruct myStruct;
    static virtual myFunA(...) = 0;
    static virtual myFunB(...) = 0;
};

class Derived1 : public Base
{
    Derived1() {  FillPointers();  }
    static virtual myFunA(...) {...};
    static virtual myFunB(...) {...};
};

class Derived2 : public Base
{
    Derived2() {  FillPointers();  }
    static virtual myFunA(...) {...};
    static virtual myFunB(...) {...};
};

int main()
{
    Derived1 d1;
    Derived2 d2;
    // Now I have two objects with different functionality
}

Ответы [ 12 ]

2 голосов
/ 27 апреля 2010

Очевидный способ такой: FillPointers реализован в каждом производном классе.

class Base
{
private:
    CStruct myStruct;
};

class Derived1 : public Base
{
 private:
    static FillPointers() { myStruct.funA = myFunA; myStruct.funB = myFunB; ...}
    Derived1() {  FillPointers();  }
    static myFunA(...) {...};
    static myFunB(...) {...};
};

Однако вы можете избежать этого, используя магию шаблонов ...

2 голосов
/ 27 апреля 2010

Виртуальные функции - это, по сути, скрытые указатели на функции. Они просто указывают на разные функции для разных классов. Чтобы смоделировать поведение виртуальной функции, сохраните где-нибудь указатель функции, а затем для «переопределения» просто переназначьте его на другую функцию.

В качестве альтернативы вы можете проверить это, но я думаю, что интерфейсы имеют довольно хорошую двоичную совместимость. Возможно, вам не удастся представить интерфейс C ++, состоящий полностью из чисто виртуальных функций, при условии, что все параметры и возвращаемые типы имеют согласованный двоичный формат (например, типы C). Это не стандарт, но он может быть достаточно портативным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...