2016-08-14 4 views
0

Является ли это приведение типов в C++ или я вижу вещи?Является ли это типизацией? Что это?

((YesNoQuestion*)first)->setAnswer(false); 
    ((MultipleAnswerQuestion*)second)->setAlternative(2, "City2"); 
    ((MultipleAnswerQuestion*)second)->setCorrectAlternative(2); 

И почему это делается вместо того, чтобы просто

first->setAnswer(false); 
    second->setAlternative(2, "City2"); 
    second->setCorrectAlternative(2); 

или

((YesNoQuestion)first)->setAnswer(false); 
    ((MultipleAnswerQuestion)second)->setAlternative(2, "City2"); 
    ((MultipleAnswerQuestion)second)->setCorrectAlternative(2); 

Не указатель обеспечивает достаточную «идентичность», чтобы сделать функции-члены класса детского жизнеспособного для родительского класса?

И зачем нужны типы указателей? Это потому, что объекты вопроса - это указатели, что новый тип тоже должен быть указателем?


Контекст:

Это ответы от старого экзамена 5-6 лет назад, и теперь все в отпуске, так что я не могу спросить профессора, которые сделали это, но они сделали это в основном -file:

#include "MultipleAnswerQuestion.h" 
#include "YesNoQuestion.h" 

int main() 
{ 
    Question *first = NULL; 
    Question *second = NULL; 

    string alt[] = {"City1", "City2", "City3"}; 
    first = new YesNoQuestion("Some statement here"); 
    second = new MultipleAnswerQuestion("Some question here", alt, 3, 0); 

    ((YesNoQuestion*)first)->setAnswer(false); 
    ((MultipleAnswerQuestion*)second)->setAlternative(2, "City2"); 
    ((MultipleAnswerQuestion*)second)->setCorrectAlternative(2); 

    first->print(); //Prints Q 
    second->print(); //Prints Q 

} 

Аннотация BaseClass: Question(string question = "");

Дети:

YesNoQuestion(string question = "", bool answer = true); 

MultipleAnswerQuestion(string question, string alternatives[], 
         int nrOfAlternatives, int correctAnswer); 
+1

Кажется, с стиле вентиляционный. Базовый класс Question может не предоставлять этих членов. – 0lakan0

+0

sidenote: в C++ лучше использовать dynamic_cast, поскольку он фактически выполняет некоторую проверку – 0lakan0

+0

Еще одно побочное: это плохой стиль C++. 1. С C++ 11 вы должны использовать 'nullptr' вместо' NULL'. 2. С C++ 11 вы должны использовать 'std :: unique_ptr' вместо необработанных указателей. 3. Еще до C++ 11 отсутствует 'delete' (с помощью' std :: unique_ptr' устраняется необходимость в 'delete'). –

ответ

0

Это тип разливки, используемый для полиморфизма. Первый вариант, который вы предложили, будет работать только в том случае, если базовый класс Question имеет виртуальные методы для setAnswer, setAlternative и setCorrectAlternative. Если нет, то вам нужно будет преобразовать указатель в хороший класс, чтобы метод был найден. Второй вариант не будет работать, потому что first и second являются указателями, поэтому их значения являются адресами. Интерпретация этих адресов как объектов класса не имела бы смысла сама по себе.

+0

Это отвечало на все мои вопросы, тывм. –

1

Это зависит от того, как именно определяются ваши классы, но я предполагаю, что ваш Question класс не имеет setAnswer метод, который принимает логическое значение. И так как first - это указатель Question, а не указатель YesOrNoQuestion, то вы не можете вызвать YesOrNoQuestion методы на нем.

Тот факт, что first фактически указывает на объект YesOrNoQuestion, не имеет значения, поскольку компилятор должен иметь возможность определить во время компиляции, является ли вызов действительным, чисто основанный на типе переменной.

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

0

(Type*) часто знают, как отливка C-стиле, в основном это выбрать один из: const_cast, static_cast, reinterpret_cast. Мне не нравится последний, поэтому я бы использовал один из них.

Причина, по которой делается бросок, наиболее вероятно потому, что Question не содержит методов, которые вызывают. Почему у общего вопроса есть setAnswer(), который принимает bool?

В этом случае, я бы написал что-то вроде следующего:

YesNoQuestion *firstTyped = new YesNoQuestion("Some statement here"); 
MultipleAnswerQuestion *secondTyped = new MultipleAnswerQuestion("Some question here", alt, 3, 0); 

Question *firstUntyped = firstTyped; 
Question *secondUntyped = secondTyped;  

firstTyped->setAnswer(false); 
secondTyped->setAlternative(2, "City2"); 
secondTyped->setCorrectAlternative(2); 

firstUntyped->print(); //Prints Q 
secondUntyped->print(); //Prints Q 
+0

Хорошая информация, я прочь прочитать о них всех. Благодарю. –

+0

_ «Почему общий вопрос имеет setAnswer(), который принимает bool?» _ То, что он не делает и не может, означает, что вы не можете использовать виртуальную отправку, а это значит, что вам нужны эти жестко закодированные броски, что означает, что ваш дизайн программы в корне ошибочен. Этот сценарий никогда не должен возникать в первую очередь. –

+0

@LightnessRacesinOrbit, который в предположении, что вы используете объект Question для этого, в то время как он может иметь метод 'createEditor()', который может скрывать необходимость 'setAnswer()' – JVApen

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