Быстрый вопрос по объявлению функций. Допустим, у меня есть следующий код:
class a{
int var;
/* stuff*/
}
class b : a{
/* other stuff*/
}
class c : a{
/* more other stuff*/
}
class d{
myFunctionThatWantsTheIntNamedVar(SubClassOfClassA SomeClassUnknownAtCompileTime);
}
и myFunctionThatWantsTheIntNamedVar () хочет именно этого, целое число (называемое var), объявленное в базовом классе a. В функцию в классе d может быть передан экземпляр класса b или класса c, который не известен во время компиляции (только во время выполнения).
Есть ли способ, которым я могу кратко объявить функцию, которая может взять либо класс b или c и получить ту же самую базовую переменную?
За это время я объявил два метода в классе d следующим образом:
class d{
myFunctionThatWantsTheIntNamedVar(c aClassCInstance);
myFunctionThatWantsTheIntNamedVar(b aClassBInstance);
}
это нормально и все, но код в этих двух методах является ИДЕНТИЧНЫМ … И из моего понимания объектно-ориентированного программирования, если код идентичен, вы сможете объединить его в лучшую функцию.
Есть мысли по этому поводу? Просто искать лучшие практики или другие советы здесь, так как я работаю в небольшой компании, и иногда мне сложно получить обратную связь.
РЕДАКТИРОВАТЬ: извините, у меня была ошибка в моем коде, изменил его с:
myfunctionThatWantsTheInNamedVar(a aClassAInstance);
чтобы:
myfunctionThatWantsTheInNamedVar(c aClassCInstance);
моя вина.
Предоставьте общедоступный метод доступа, который дает доступ к переменной, и убедитесь, что вы не скрываете ее имя в классе b и классе c.
class a{
int var;
/* stuff*/
public:
const int& getVar() const { return var; }
int& getVar() { return var; }
};
Затем возьмите ссылку на a
в функции ойур:
class d{
public: // you probably want a public member function
myFunctionThatWantsTheIntNamedVar(const a& theA) {
int n = theA.getVar();
}
Тогда вы можете позвонить с b
или же c
экземпляры:
b b0;
c c0;
d d0;
d0.myFunctionThatWantsTheIntNamedVar(b0);
d0.myFunctionThatWantsTheIntNamedVar(c0);
Имейте в виду, что в вашем коде переменная var
является личным, а также безнаказанность в классах b
а также c
, Чтобы это работало, вам нужно сделать публичное наследование:
class b : public a { .... };
class c : public a { .... };
class d{
myFunctionThatWantsTheIntNamedVar(const a& anA);
}
Если вы действительно хотите запретить фактический экземпляр a, но разрешить любой производный класс, вы можете использовать Идентификацию типа времени выполнения, чтобы вызвать исключение, если это на самом деле a, а не производный класс.
Если у вас есть чисто виртуальная функция в a, которая не имеет реализации (но требует b и c для предоставления реализаций), то вы даже не можете создать экземпляр a, поэтому проверка не требуется. Но это только в том случае, если у вас была причина для этого — я бы не предложил такую искусственную конструкцию именно для этого.
Почему бы не это:
class d{
void myFunction(A a) {;}
};
если вы говорите, что код для обеих ваших функций одинаков, это означает, что они не используют ничего, что отличается между классами C и B. Другими словами, вы используете только то, что является общим для B и C, и это на самом деле класс А.
Конечно (A a) это просто иллюстрация. Вы должны объявить аргумент как (const A& а) или (A * pA), в зависимости от того, что вам нужно. Кроме того, я предполагаю, что var
каким-то образом виден за пределами своей иерархии, делая его общедоступным или лучше, инкапсулируя его в общедоступный метод доступа.