调用虚拟成员类的方法



我知道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;
}

最新更新