C++;虚拟值之间的差值=0;和空函数 我现在学习C++,面向对象,我总是看到这个: class SomeClass{ virtual void aMethod()=0; } class AnotherClass{ void anotherMethod(){/*Empty*/} } class SomeClassSon : public SomeClass{ void aMethod(){/*Also Empty*/} }
这三种方法的区别是什么?虚拟值等于零,为空,而虚拟值由于是继承的,因此为空C++;虚拟值之间的差值=0;和空函数 我现在学习C++,面向对象,我总是看到这个: class SomeClass{ virtual void aMethod()=0; } class AnotherClass{ void anotherMethod(){/*Empty*/} } class SomeClassSon : public SomeClass{ void aMethod(){/*Also Empty*/} },c++,oop,class,methods,C++,Oop,Class,Methods,这三种方法的区别是什么?虚拟值等于零,为空,而虚拟值由于是继承的,因此为空 为什么我不能让SomeClassSon方法像父方法一样,虚空等于零?区别在于虚空aMethod()=0是a,意思是: SomeClass成为抽象基类, 这意味着它不能被实例化 从SomeClass继承的任何类都必须实现aMethod,否则它也将成为无法实例化的抽象基类 请注意,任何具有一个或多个纯虚函数的类都自动成为抽象基类。纯虚使类抽象。空的非虚拟方法没有任何作用-如果您试图调用它,它只会导致链接器错误。相反,您不能尝
为什么我不能让SomeClassSon方法像父方法一样,虚空等于零?区别在于
虚空aMethod()=0
是a,意思是:
SomeClass
成为抽象基类,
这意味着它不能被实例化SomeClass
继承的任何类都必须实现aMethod
,否则它也将成为无法实例化的抽象基类请注意,任何具有一个或多个纯虚函数的类都自动成为抽象基类。纯虚使类抽象。空的非虚拟方法没有任何作用-如果您试图调用它,它只会导致链接器错误。相反,您不能尝试调用纯的
虚拟的(除非您尝试从构造函数调用它,这是很糟糕的),因为编译器不允许您创建该对象
还有一个逻辑上的区别-标记为virtual
的方法通过继承链是虚拟的-其他方法只是常规方法。纯虚拟函数(您的第一个示例,=0
)意味着必须在派生类中重写该函数才能实例化该类的对象
第二个基本上只是一个不做任何事情的成员函数。由于函数具有不同的名称,并且类与SomeClass
无关,因此这两个类根本不会相互影响
第三个重写纯虚函数,因此可以实例化SomeClassSon
,但在派生类中被重写的函数不起任何作用。声明aMethod()=0告诉编译器必须在子类中提供此方法。任何未实现该方法的子类都无法实例化。这有助于确保基类的任何对象都将实现该方法。您所指的“等于0”称为“纯虚拟”。这是一个需要实例化的子类必须实现的函数,而不是提供基本功能,这意味着父类将定义必须存在的功能,但父类不知道子类将如何实现。注意,这使得类变得抽象,因为它不能被实例化。例如,我可能想定义一个我可以继承的“哺乳动物”类,我希望它的子类以某种方式行事——但我不能简单地制造一个“哺乳动物”。相反,我会创建一个“Giraffe”类,并确保它的行为符合预期
这个问题也解释了
您所指的“Empty”函数是定义了函数并可以调用的功能,但它什么也不做。对于您的
class SomeClass{
virtual void aMethod()=0;
}
纯虚方法的存在使类变得抽象。一旦类中有一个这样的纯虚拟方法,=0
,就不能实例化该类。此外,任何派生类都必须实现纯虚拟的aMethod()
,否则它也将成为抽象类
在派生类中,覆盖上面的纯虚方法,这使派生类成为非抽象类。您可以实例化这个派生类
但是,在派生类中,方法的主体是空的,对吗?这就是为什么你的问题是有意义的:为什么不让这个类也成为纯虚拟的呢。嗯,你的课可能需要其他方法。如果是这样的话,SomeClass
不能实例化(有一个纯虚拟方法),而子类SomeClassSon
可以实例化
这同样适用于您的另一个类
,它可以被实例化,与SomeClass
SomeClass相反;s、 aMethod()
不是有效的调用。区别在于,基类中的=0
,每个派生类都必须实现该方法。@DavidSchwartz-如果该类被实例化,则必须实现该函数。如果函数没有实现,则类是抽象的。也许你的意思是对的,但说错了:从SomeClass
派生的类不会被强制实现函数,但如果它们没有实现,那么它们也是抽象的。