проверить переопределена ли виртуальная функция
От: Wawan Россия http://www.wawan.ru/resume
Дата: 31.08.15 16:29
Оценка:
возникло желание проверить в базовом классе переопределена ли виртуальная функция или она по прежнему вызывает функцию из базового класса
реально ли такое сделать на с++ ?
Re: проверить переопределена ли виртуальная функция
От: Alexander G Украина  
Дата: 31.08.15 16:39
Оценка: 37 (2) -1
Здравствуйте, Wawan, Вы писали:

W>возникло желание проверить в базовом классе переопределена ли виртуальная функция или она по прежнему вызывает функцию из базового класса

W>реально ли такое сделать на с++

#include <iostream>
using namespace std;

struct A
{
    virtual int a();
    virtual int b();
};

struct B : A
{
    virtual int a();
};

int main() {
    std::cout << std::is_same<decltype(&A::a), decltype(&B::a)>::value << '\n'; // 0
    std::cout << std::is_same<decltype(&A::b), decltype(&B::b)>::value << '\n'; // 1
    return 0;
}
Русский военный корабль идёт ко дну!
Re: проверить переопределена ли виртуальная функция
От: watchmaker  
Дата: 31.08.15 18:16
Оценка: 44 (4) +1
Здравствуйте, Wawan, Вы писали:

W>возникло желание проверить в базовом классе переопределена ли виртуальная функция или она по прежнему вызывает функцию из базового класса

W>реально ли такое сделать на с++ ?
Если известен только базовый класс и нет доступа к декларациям всех наследников, то нет (для случая, когда декларации наследников известны, способ уже показали).

Хотя в некоторых компиляторах есть расширения, позволяющие провести такой тест. Например, в gcc:
struct A {
  virtual int foo();  
  virtual int bar();
};

bool hasOriginalFoo(A& u) {
  typedef int (*fptr)(A*);
  return (fptr)(u.*(&A::foo)) == (fptr)(&A::foo);
}

Такая проверка обнаружит переопределение метода foo() у любых наследников A в пределах программы, даже если они не доступны в текущей единице трансляции.

Для других компиляторов, не имеющих аналога такому расширению, можно разве что взять C++ABI и посмотреть как там следует сделать нужную проверку. Так как С++ABI существут несколько разных, то для каждого придётся писать свой код и следить чтобы проверка для одной платформы не вызвалась для другой. В общем, хотя это и возможно, но настолько муторно и сложноподдерживаемо, что так почти никто не делает. И тебе не советую :)
Re[2]: проверить переопределена ли виртуальная функция
От: Wawan Россия http://www.wawan.ru/resume
Дата: 31.08.15 23:42
Оценка:
спасибо, похоже на то что нужно, если еще в студии это сработает то может пригодиться
Re[3]: проверить переопределена ли виртуальная функция
От: SaZ  
Дата: 01.09.15 10:01
Оценка: +3
Здравствуйте, Wawan, Вы писали:

W>спасибо, похоже на то что нужно, если еще в студии это сработает то может пригодиться


Присоединюсь к предыдущему отвечающему — это не нужно. Это явный признак неправильного понимания ООП (или неправильной архитектуры). Если такое понадобилось — то это типичный костыль. Решать, конечно, вам. Но в большинстве случаев такие ситуации разруливаются при корректном использовании паттернов.
Re[4]: проверить переопределена ли виртуальная функция
От: Wawan Россия http://www.wawan.ru/resume
Дата: 01.09.15 16:01
Оценка:
Здравствуйте, SaZ, Вы писали:

SaZ>Здравствуйте, Wawan, Вы писали:


W>>спасибо, похоже на то что нужно, если еще в студии это сработает то может пригодиться


SaZ>Присоединюсь к предыдущему отвечающему — это не нужно. Это явный признак неправильного понимания ООП (или неправильной архитектуры). Если такое понадобилось — то это типичный костыль. Решать, конечно, вам. Но в большинстве случаев такие ситуации разруливаются при корректном использовании паттернов.

знаю что это грех, обещаю этот код никто не увидит )
Отредактировано 01.09.2015 16:02 Wawan . Предыдущая версия .
Re[2]: проверить переопределена ли виртуальная функция
От: qqqqq  
Дата: 01.09.15 16:16
Оценка:
А если в базовом классе несколько функций с одним и тем же именем но с разными аргументами, то как проверить их все?
Re[3]: проверить переопределена ли виртуальная функция
От: watchmaker  
Дата: 01.09.15 17:21
Оценка:
Здравствуйте, qqqqq, Вы писали:

Q>А если в базовом классе несколько функций с одним и тем же именем но с разными аргументами, то как проверить их все?


В чём сложность-то? Проверить первую, потом вторую, третью, и так далее пока все не переберёшь. Добавляешь каждый раз свою сигнатуру функции при взятии адреса чтобы из множества выбрать единственно нужную. Синтаксис как в учебнике:
(int (A::*)())(&A::foo)  // указатель на int A::foo()
(int (A::*)(int))(&A::foo)  // указатель на int A::foo(int)
(int (A::*)(double))(&A::foo)  // указатель на int A::foo(double)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.