Вызов реализации производного класса чистой виртуальной функции статически с использованием функции в базовом классе
Это обсуждение обсуждается в другом месте в stackru, но я действительно не нашел четкого ответа на свой вопрос.
Моя установка такова:
class BaseClass
{
virtual short return_number_for_thing1(std::string thing1)=0; //note the pure virtual
virtual short return_number_for_thing2(std::string thing2)=0;
virtual short return_number_for_thing(std::string thing); //virtual is probably not necessary here, I can get rid of it if need be
}
short BaseClass::return_number_for_thing(std::string thing)
{ //pretend thing1 and thing2 are enum'ed somewhere
if (thing == thing1) return return_number_for_thing1(thing);
else if (thing == thing2) return return_number_for_thing2(thing);
}
class DerivedClass1 : BaseClass
{
short return_number_for_thing1(std::string thing1);
short return_number_for_thing2(std::string thing2);
}
class DerivedClass2 : BaseClass
{
short return_number_for_thing1(std::string thing1);
short return_number_for_thing2(std::string thing2);
}
У меня вопрос, почему я не могу написать код, подобный этому:
short number_i_want = DerivedClass2::return_number_for_thing(thing);
Я вроде понимаю, что пытаться вызвать return_number_for_thing из указателя BaseClass не имеет смысла, так как он не знает, вызывать ли подпрограммы для DerivedClass1 или DerivedClass2, но если я дам ему область действия DerivedClass2, не должно ли это быть смог понять что я хочу? На данный момент я создаю пустой экземпляр DerivedClass2 или DerivedClass1, когда мне это нужно, но мне кажется, что мне не нужно этого делать.
3 ответа
В C++ виртуальное и статическое не смешиваются.
virtual
= конкретная операция зависит от типа объекта.static
= вам не нужен объект.
Однако, конечно, можно представить себе такую вещь. Если бы в C++ было что-то вроде мета-типов, позволяющее вам рассматривать обычные типы как объекты, то это уже не было бы такой странной идеей.
Псевдокод (используя воображаемый синтаксис):
void f(Class base_class)
{
base_class.StaticMethod();
}
struct Base
{
virtual static StaticMethod(); // impossible in C++
};
struct Derived : Base
{
virtual static StaticMethod(); // impossible in C++
};
f(Base); // impossible in C++
f(Derived); // impossible in C++
Желание создать что-то вроде статических виртуальных функций иногда является признаком реальной потребности (которую С ++ не может выполнить "из коробки"): рассматривать типы как объекты.
Вы можете сделать функцию виртуальной или статической, а не обе.
Виртуальная функция должна иметь указатель vtable, для которого требуется экземпляр объекта, статическая функция не может (по определению) иметь экземпляр, к которому она относится.
Если вы объявите функции как, например:
virtual short return_number_for_thing1(std::string thing1)=0;
тогда вы должны создать экземпляр и использовать его, например, m_Instance->return_number_for_thing1(...)
(но поскольку вы не используете переменные-члены, может показаться, что это не имеет смысла).
Если вы объявите функции как статические:
static short return_number_for_thing1(std::string thing1)
Тогда вы должны вызывать функцию статически BaseClass::return_number_for_thing1()
, если вы предоставляете статическую версию той же функции в производном классе, она теперь становится переопределением, и вы выбираете, какую функцию вызывать во время компиляции, либо BaseClass::return_number_for_thing1
или же DerivedClass::return_number_for_thing1
..
Ваш вопрос все еще не имеет смысла, как указано, так как вы не можете использовать виртуальную функцию статически. Статически подразумевается, что вы хотите использовать его без какого-либо экземпляра, он просто похож на функцию ac, но скрыт в пространстве имен класса (и соблюдает конфиденциальность). Виртуальные функции требуют экземпляра для работы.
Изготовление static virtual
методы невозможны, цитируя стандарт C++11 N3337 - 10.3.10:
[Примечание: виртуальный спецификатор подразумевает членство, поэтому виртуальная функция не может быть функцией, не являющейся членом (7.1.2). Виртуальная функция также не может быть статическим членом, поскольку вызов виртуальной функции зависит от конкретного объекта для определения, какую функцию вызывать. Виртуальная функция, объявленная в одном классе, может быть объявлена другом в другом классе. —Конечная записка]