2015-08-19 3 views
1

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

Редактировать: Я хочу, чтобы setInput имел разную функциональность для каждого производного класса. Это task.setInput(derived2) звонки setInput(BaseClass* object), уничтожает его для меня. Это позволяет пропустить использование api. Поэтому я думаю, что мне нужно переключить функциональность в методе. Думаю, используя dynamic_cast это сделает? Большое спасибо. :-)

class BaseClass { virtual void xy() .. } 
class Derived1Class : BaseClass { .. } 
class Derived2Class : BaseClass { .. } 
class Derived3Class : Derived2Class { .. } 

class Task { 
    void setInput(BaseClass* object); 
    void setInput(Derived1Class* object); 
    void setInput(Derived2Class* object); 
    void setInput(Derived3Class* object); 
} 

main() { 
    BaseClass* base = new BaseClass(); 
    Derived1Class* derived1 = new Derived1Class(); 
    BaseClass* derived2 = new Derived2Class(); 
    Derived2Class* derived3 = new Derived3Class(); 
    Task* task = new Task(); 
    task.setInput(base); 
    task.setInput(derived1); 
    task.setInput(derived2); 
    task.setInput(derived3); 
} 
+2

Это зависит от того, что вы подразумеваете под «работой», что перегрузка вы ожидаете 'task.setInput (производный2)' для вызова? –

+1

Вы имеете в виду многократную отправку? (Это означает, что полиморфизм основан на всех аргументах, а не только на этом.) –

+2

Я думаю, вы хотите, чтобы 'task.setInput (производный2)' вызывал перегруз с аргументом Derived2Class *, который здесь ** не является ** здесь. Полиморфизм в C++ работает только для ** субъекта ** (то есть объекта, на который вызывается функция), а не для аргументов. Как упоминает @ TheodorosChatzigiannakis, для этого требуется метод, известный как «множественная отправка», большинство языков ООП (например, C++, а также Java для другого примера) не поддерживают из коробки, но могут быть «эмулированы» с использованием шаблона проектирования Visitor. См. Https://en.wikipedia.org/wiki/Multiple_dispatch – leemes

ответ

3

Как говорят другие ответы, вызовы функций будут:

void setInput(BaseClass* object);   // F0 
void setInput(Derived1Class* object);  // F1 
void setInput(Derived2Class* object);  // F2 
void setInput(Derived3Class* object);  // F3 

task.setInput(base);      // calls F0   
task.setInput(derived1);     // calls F1 
task.setInput(derived2);     // calls F0 
task.setInput(derived3);     // calls F2 

Так функция называется зависит от типа указателя, а не тип объекта он указывает на (не наиважнейшей полиморфизма на функцию аргументы).

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

недействительного setInput (BaseClass * объект); // F0

тогда все последующие вызовы будут компилироваться и назвать FO:

task.setInput(base);      // would call F0   
task.setInput(derived1);     // would call F0 
task.setInput(derived2);     // would call F0 
task.setInput(derived3);     // would call F0 

Компилятора будет способствовать соответствию точных типов до преобразования от dervied к базовому типу, при разработке которой функция для вызова.

1

По существу, что вы спрашиваете, является ли параметр функции подчиненным полиморфизму. Это действительно так. Указатель производного класса может быть неявно преобразован в указатель базового класса. Поэтому достаточно иметь один setInput.

class Task { 
    void setInput(BaseClass* object); 
} 

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

Но если вам нужно перегрузить setInput таким образом, я бы сначала попытался сделать setInput членом класса Base/Derived.

+1

да, я, возможно, пропустил динамическое ключевое слово в заголовке и просто прочитал тело. – Paani

+0

Thx. Сделать setInput членом класса Base/Derived не имеет смысла, потому что я хочу работать с частными полями задачи. – GiCo

5

Перегрузка функции выполняется во время компиляции, основанная на статическом типе аргумента, а не на динамическом типе времени выполнения. Так что-то вроде:

BaseClass* derived2 = new Derived2Class(); 
task.setInput(derived2); 

будет вызывать перегрузку setInput принимая BaseClass*неDerived2Class*.

Так что ответ зависит от того, какое поведение вы ожидали, но я предполагаю, что ответ нет.

+0

Thx. Да, похоже, это невозможно в том, как я хочу его реализовать. – GiCo

Смежные вопросы