我知道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。
如何从get_Wheels()
调用成员类Parts
中的Machine*
或任何其他功能?由于您无法保证函数具有实现,因此您似乎必须知道在调用Machine
之前您拥有的get_wheels()
是什么类型。
答案 0 :(得分:3)
对不起,我的朋友,但C ++在这个意义上没有“虚拟课程”。它具有虚拟的类,因为它们具有一些纯虚方法,因此它们无法实例化(参见this question) - 但不是您所描述的内容。
正如@StephenMWebb指出的那样 - 您链接到的维基百科文章并未声称是关于C ++的......
答案 1 :(得分:3)
您发布的代码不是C ++,因为此语言不支持您描述的概念中的虚拟类。
答案 2 :(得分:0)
让我们将其转换为真正的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 ++中,没有地方或需要“虚拟类”的概念。任何类都可以继承任何其他类(无论是否内部),只要它是可访问的,就像上面的示例一样。如你所见,即使完全不相关的类也可以从内部类继承......
另一方面,如果我们希望能够覆盖,我们需要显式地声明函数虚拟 - 好吧,第一个被覆盖的至少,实际上覆盖的那些是隐式的虚拟。长期以来一直被认为是重写虚拟甚至覆盖函数的好习惯,因为C ++ 11是冗余的,因为override
关键字也意味着虚拟性......显然,在本文的示例语言中,函数总是如此隐含虚拟...
答案 3 :(得分:0)
Another effort:
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;
}