Как проверить, расширяет ли один класс C ++ другой (например, если этот другой был интерфейсом)? - PullRequest
2 голосов
/ 16 января 2011

Так, как правило, имея

class A { ... };
class B { ... };
class C: public A, public B {};  // C inherits from A and B.

когда мы создаем экземпляр C и хотим передать его в какую-то функцию, проверяем ли мы, что класс, который мы передаем функции, расширяет A?

Ответы [ 2 ]

9 голосов
/ 16 января 2011

C определяется как наследующий от A, поэтому нет необходимости проверять:

Обязательно, чтобы экземпляр C также был AB).

Однако, если у вас есть функция, принимающая A в качестве параметра, вы можете использовать dynamic_cast<>, чтобы проверить, является ли экземпляр на самом деле C:

void function(const A& a)
{
  const C* c = dynamic_cast<const C*>(&a);

  if (c)
  {
    // a is an instance of C and you can use c to call methods of C
  } else
  {
    // a is not an instance of C.
  }
}

Однако, чтобы это работало, базовый тип класса должен быть полиморфным (он должен иметь хотя бы виртуальный метод).

3 голосов
/ 16 января 2011

Единственный раз, когда вам нужно это сделать, это во время компиляции, поскольку неявное преобразование работает везде.Но если вы хотите увидеть, является ли некоторый тип T базисом некоторого типа S, то вы можете использовать SFINAE (или просто использовать is_base_of <>):

template < typename T, typename S >
struct is_base_of // checks if T is a base of S
{
  typedef char (yes&) [1];
  typedef char (no&)  [2];

  void yes check(T*);
  void no  check(...);

  enum { value = sizeof(check(static_cast<S*>(0))) == sizeof(yes); }
};
...