虚之间的C++差=0;和空函数
C++ difference between virtual = 0; and empty function
我现在正在学习C++,OO方面,我一直看到这一点:
class SomeClass{
virtual void aMethod()=0;
}
class AnotherClass{
void anotherMethod(){/*Empty*/}
}
class SomeClassSon : public SomeClass{
void aMethod(){/*Also Empty*/}
}
这三种方法有什么区别?virtual等于零,是空的,而virtual由于是继承的,所以是空的。
为什么我不能像父亲一样制作SomeClassSon方法,虚拟空隙等于零?
用于
class SomeClass{
virtual void aMethod()=0;
}
纯虚拟方法的存在使类抽象。一旦类中有一个这样的纯虚拟方法=0
,就无法实例化该类。更重要的是,任何派生类都必须实现纯虚拟aMethod()
,否则它也将成为一个抽象类。
在派生类中,覆盖上面的纯虚拟方法,这会使派生类变得非抽象。您可以实例化这个派生类。
但是,在派生类中,方法的主体是空的,对吗?这就是为什么你的问题是有意义的:为什么不让课堂也成为纯粹的虚拟课堂呢。好吧,你的类可能需要其他方法。如果是这样,SomeClass
就不能实例化(有一个纯虚拟方法(,而子类SomeClassSon
可以是.
这同样适用于您的AnotherClass
,它可以实例化,与SomeClass
相反。
不同之处在于virtual void aMethod() = 0
是纯虚拟函数,这意味着:
- CCD_ 8成为抽象基类,这意味着它不能被实例化
- 任何继承自
SomeClass
的类都必须实现aMethod
,否则它也将成为无法实例化的抽象基类
请注意,任何具有一个或多个纯虚拟函数的类都自动成为抽象基类。
您所指的"等于0"被称为">纯虚拟"。这是一个需要实例化的子类必须实现的函数,而不是提供基本功能,这意味着父类将定义必须存在的功能,但父类不知道子类将如何实现。请注意,这使类变得抽象,因为它无法实例化。例如,我可能想定义一个我可以继承的"哺乳动物"类,我希望它的孩子以某种方式行事——但我不能简单地制作一个"哺乳动物"。相反,我会创建一个"长颈鹿"类,并确保它的行为像它应该做的那样
这个SO问题也解释了这一点。
你所指的"Empty"函数是一种功能,它定义了函数并可以调用,但什么都不做。
声明aMethod((=0告诉编译器必须在子类中提供此方法。任何未实现该方法的子类都不能实例化。这有助于确保基类的任何对象都将实现该方法。
纯虚拟函数(您的第一个例子是=0
(意味着该函数必须在派生类中重写,才能实例化该类的对象。
第二个基本上只是一个什么都不做的成员函数。由于函数有不同的名称,并且类与SomeClass
无关,因此两者根本不会相互影响。
第三个重写纯虚拟函数,因此可以实例化SomeClassSon
,但在派生类中,重写的函数什么也不做。
纯virtual
使类抽象。空的非虚拟方法没有任何作用-如果你试图调用它,它只会导致链接器错误。相比之下,你不能尝试调用纯virtual
(除非你试图从构造函数调用它,这无论如何都很糟糕(,因为编译器不允许你创建该对象。
还有一个逻辑差异——标记为virtual
的方法将通过继承链是虚拟的——其他方法只是常规方法。
- 编译器如何在使用SFINAE的函数和标准函数之间确定两者是否可行
- 填充上编译器生成的复制构造函数之间的不一致
- 为什么不允许成员函数和非成员函数之间的函数重载?
- 如何在"push_*()"和"emplace_*()"函数之间进行选择?
- 仅具有运算符()的结构和普通函数之间的实际区别
- 当两者都调用时,删除和析构函数之间的区别?
- Release() 和析构函数之间的区别?
- 调用 "project" 函数和调用 DLL 函数之间的区别
- C++模板和非模板函数之间的重载解析
- std::shared_ptr 和 std::unique_ptr 构造函数之间的不对称
- C++ 和 Lua 函数之间的交互与 3D 矢量参数
- 在结构函数之间传递文件路径 C++ 编辑:修复LNK2019错误
- 在C++同名的顶级函数之间进行选择
- 在成员函数之间传递const变量为数组的索引
- Helgrind 报告了使用 Singleton 及其构造函数之间可能存在的竞争
- 函数模板和函数之间奇怪的不一致"normal"
- 在c#和c函数之间传递值和指针
- 在C++中调用 malloc() 与"operator new"函数之间的实现差异
- 在函数之间传递相同的数组
- C++编译错误是由于使用 std::move 时运动构造函数与其他非运动构造函数之间的冲突