2016-11-09 1 views
-2

Так сказать, у меня есть следующиеC++ Изменить Наследуется класса

  • Класс A - Класс Main (не может изменить)
  • Класс B - Базовый класс
  • Класс C - Alternate базового класса

Класс А определяется как

Class A : public Class B 
{}; 

я бы начал менять его программным образом, чтобы вместо этого было Class A : public Class C?

Причина, заключающаяся в том, что я хочу, чтобы класс C был пронизан минималистичной версией класса B для целей модульного тестирования. Так что мне нужен способ, чтобы порождать версию класса А без изменения класса А, который затем использует методы класса С, а не класс В.

Надеюсь, это имеет смысл?

+1

Короткий ответ: вы не можете. C++ не работает таким образом. –

+1

Это не то, как работает система статического типа. – DeiDei

+2

Как насчет этого. Назовите оба класса 'B', но настройте свой проект или систему сборки, чтобы убедиться, что используется один и только один из них. –

ответ

1

Вы можете использовать шаблоны и изменять его во время компиляции:

template<typename T> 
class AT: public T { /* ... */ }; 

Теперь, где-то, вы можете сделать это:

#ifdef DEBUG 
using A = AT<C>; 
#else 
using A = AT<B>; 
#endif 

В противном случае, если вы хотите сделать это во время выполнения, вы должны скорее использовать композицию по наследованию, например:

struct A { 
    I subclass; 
}; 

// ... 

struct B: I {}; 
struct C: I {}; 

Выполнение этого действия, вы можете ввести триггер в вашем программном обеспечении, которое просто заставляет впрыскивать экземпляр B или C в вашем случае A.
До тех пор, пока экземпляр A пересылает запросы к базовому классу, не имеет значения, что является производным, это имеет значение для его интерфейса.


Для ответа на вопрос: вы не можете изменить тип базового класса во время выполнения.
Если A наследует от B, то все.

0

В свете вашего комментария есть несколько ответов, но реальный ответ - не использовать наследование.

  1. Применения Состав:

    class wrapper 
    { 
        thing_you_want_to_mock& thingie; 
    
        // all the wrapped functionality 
    }; 
    

    Здесь вы можете просто создать макет thing_you_want_to_mock и проверить обертку с фиктивным объектом. Проблема здесь в том, что я предполагаю, что thing_you_want_to_mock имеет переопределяемый интерфейс, что, вероятно, не так для вас.

  2. Использование шаблонных Состав:

    template<typename ThingYouWantToMock> 
    class wrapper 
    { 
        ThingYouWantToMock thing; 
    
        // Wrapper functions that call functions on thing 
    }; 
    

Оба являются примерами ... Strategy Pattern! В той или иной форме.