我知道virtual
在成员函数的上下文中是如何工作的,但我在网上看到一篇关于虚拟成员类的文章,这让我感到困惑。
我找到的例子是这样的:
class Machine
{
void run () {}
virtual class Parts
{
};
};
// The inner class "Parts" of the class "Machine" may return the number of wheels the machine has.
class Car: public Machine
{
void run() {
cout << "The car is running." << endl;
}
class Parts
{
int get_Wheels () {
cout << "A car has 4 wheels." << endl;
return 4;
}
string get_Fuel_Type () {
cout << "A car uses gasoline for fuel." << endl;
return "gasoline";
}
};
};
https://en.wikipedia.org/wiki/Virtual_class 的文章声称:
任何类类型的 Machine 对象都可以以相同的方式访问。程序员可以询问轮子的数量(通过调用get_Wheels(((,而不需要知道它是什么样的机器,机器有多少个轮子,或者所有可能的机器类型。像 get_Fuel_Type(( 这样的函数可以通过派生的类 Car 添加到虚拟类 Parts 中。
如何从Machine*
调用成员类中的get_Wheels()
或任何其他函数Parts
?似乎您必须知道您拥有哪种Machine
才能调用get_wheels()
因为您无法保证该函数具有实现。
您发布的代码不是C++,因为这种语言不支持您描述的概念中的虚拟类。
对不起,我的朋友,但从这个意义上说,C++没有"虚拟课程"。它具有虚拟的类,因为它们具有一些纯虚拟方法,因此无法实例化它们(请参阅此问题( - 但不是您所描述的内容。
正如@StephenMWebb指出的那样 - 您链接到的维基百科文章并不声称是关于C++的......
让我们将其转换为实际C++:
class Machine
{
// need to make it explicitly virtual, otherwise subclasses
// cannot override, just hide!
virtual void run () { }
protected: // otherwise, not accessible from sub classes!
class Parts // no keyword virtual!!!
{
};
};
class Car : public Machine
{
virtual void run() override
{
cout << "The car is running." << endl;
}
class Parts : Machine::Parts
// ^ but we need to inherit e x p l i c i t l y
{
int get_Wheels ();
std::string get_Fuel_Type();
}
};
class JustADemo : public Machine::Parts // Parts needs to be public for!
{
};
在C++,没有"虚拟课程"的概念。任何类都可以从任何其他类(无论是否内部(继承,只要它是可访问的,就像上面的示例中一样。如您所见,即使是完全不相关的类也可以从内部类继承......
另一方面,如果我们希望能够覆盖,我们需要显式声明函数 virtual – 好吧,至少第一个被覆盖的函数,实际上覆盖的函数是隐式的虚拟函数。长期以来,即使在覆盖功能上重复虚拟也被认为是好的做法,因为 C++11 是多余的,不过override
关键字也意味着虚拟......显然,在本文的示例语言中,函数始终是隐式虚拟的......
另一项努力:
class Parts {
public:
virtual int get_Wheels() = 0;
virtual string get_Fuel_Type() = 0;
};
class CarParts: public Parts
{
public:
virtual int get_Wheels() override {
cout << "A car has 4 wheels." << endl;
return 4;
}
virtual string get_Fuel_Type() override {
cout << "A car uses gasoline for fuel." << endl;
return "gasoline";
}
};
class Machine
{
public:
virtual void run() = 0;
};
class Car : public Machine, public CarParts{
public:
virtual void run() {
cout << "The car is running." << endl;
}
};
int main() {
Machine* ptr = new Car();
reinterpret_cast<Car*>(ptr)->run();
reinterpret_cast<Car*>(ptr)->get_Wheels();
return 0;
}