Jim*_*mmy 26 c++ terminology interface pure-virtual
所以这是我所在的框.我想了解为什么在你的接口类中有一个"虚拟析构函数"很重要.如果你可以挂到最后,你会看到为什么那些东西在引号中...我也想让所有的词汇绝对正确.到目前为止,这是我处理过程的地方:
有时您有基类,有时您有从基类继承的派生类.
如果你有一个基指针,它发现自己指向一个派生对象,你还希望从该指针指向一个派生对象的成员函数调用,就像它实际上被调用一样从派生对象中,您调用的成员函数最好在基类中声明为virtual.
接口是任何只有纯虚函数的类.如果从此接口类派生新类并实现所有纯虚函数,则最终可以创建派生类的实例.
你永远不可能有一个接口类的实例,但你可以有一个指向接口类的实例.
如果你有一个实际指向派生类对象的指针接口类(实际上,我想如果#4是正确的话,它总是必须这样),如果你决定通过它删除那个对象你的指针,如果你的接口类中没有"虚拟析构函数",你破坏派生对象的意图只会作为一个调用来执行,以破坏基础对象(即接口类),因为没有虚拟析构函数,事物永远不会达到实际调用派生对象的析构函数的程度 - 从而导致内存泄漏.
唷.好的,如果这听起来是正确的,请回答我的问题.仅仅在你的界面中声明一个虚拟析构函数就足够了:
virtual ~iFace();
Run Code Online (Sandbox Code Playgroud)
这对我来说是错误的......所以如果你像这样使析构函数变为虚拟,会发生什么:
virtual ~iFace() = 0;
Run Code Online (Sandbox Code Playgroud)
既然它们只是声明,那么它们中的任何一个都算是"接口类中的虚拟析构函数"吗?你甚至可以有一个声明但未定义的析构函数吗?只有它是纯粹的虚拟我猜...
无论如何,所以回到标题问题......我真的要尽可能快......这是拍摄的钱......如果你的"界面类中的虚拟析构函数"需要至少一个像这样的空定义:
virtual ~iFace() {};
Run Code Online (Sandbox Code Playgroud)
那个成员函数不是纯虚拟的(不能因为你给了它一个定义),因此你的类不再是一个接口(它不仅包含纯虚拟成员函数).
这意味着如果为接口定义虚拟析构函数,则不再具有接口(而只是一些抽象基类).这只是滥用语言吗?我明白发生了什么吗?
注意:这一切都来自于问自己"什么是界面?" 然后阅读这个问题的答案: 你如何在C++中声明一个接口?
希望漫长的骑行时间不会太长,但我决心完全理解这些概念及其相关的词汇.
Alo*_*ave 28
为什么Abstract class析构函数应该是虚拟的并且有一个定义?
调用delete指向Derived类对象的多态Base类指针和没有虚析构函数的Base类会导致Undefined Behavior.
所以你需要声明多态Base类的析构函数virtual.一旦声明析构函数是虚拟的,就需要为它提供一个定义.这是因为默认情况下编译器为每个类生成(定义)析构函数,但是如果您显式声明了析构函数,那么编译器就不会这样做,而是让它为您自己的destuctor提供定义.这是有道理的,因为编译器在析构函数中看到显式声明表示您想要执行一些非常重要的操作(即使您不需要这样做),它通过强制您提供给出机会定义.
误区1:C++中
有一种叫做a的东西Interface.
NO
C++作为一种语言没有提供Interface
你在C++中Interface称为an的所谓的内容Abstract class.Abstract Classes用于模拟InterfaceC++中的行为.
什么是抽象类?
根据定义,抽象类应该至少有一个纯虚函数.
误区2:
Abstract类中的所有函数都需要是纯虚拟的.
NO
Abstract classes不要求其中的所有函数都是纯虚拟的.如果Abstract具有至少一个纯虚函数,则无法创建它的对象.但是,正如您正确提到的,您可以创建指向它的指针.
误区3:
纯虚函数无法定义.
否
纯虚拟函数有一个定义是完全有效的.
为什么我需要一个Pure virtual function定义?
代码比单词更响亮,所以这是一个简单的例子:
警告:仅用于演示的未编译代码
class IMyInterface
{
int i;
int j;
public:
virtual void SetMembers(int ii, int jj)=0;
};
/*The pure virtual function cannot be inline in the class definition*/
/*So this has to be here*/
void IMyInterface::SetMembers(int ii, int jj)
{
i = ii;
j = jj;
}
class Myclass: public IMyInterface
{
int k;
int l;
public:
virtual void SetMembers(int ll, int m, int a, int b)
{
k = ll;
l = m;
IMyInterface::SetMembers(a,b);
}
};
int main()
{
MyClass obj;
obj.SetMembers(10,20,30,40);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
C++没有本机接口实体.接口实现为常规类.
因此,在C++中使类成为接口的原因并不是具有普遍一致性的东西.我个人认为一个类是一个接口,如果它没有数据成员,没有用户声明的构造函数,并且它的所有函数都是纯虚拟的 - 可能除了它的析构函数 - 并且它的所有基类(如果有的话)也是接口.如果一个类不太适合所有这些属性,我可能会将它称为"胖"接口(通常不是恭维!).
如果要通过指向基类的指针(例如"接口"类)删除动态分配的多态类,则必须声明基类析构函数virtual.这意味着它必须是用户声明的析构函数,而不是隐式声明的析构函数,它不是virtual.
一旦明确声明了析构函数,就必须为它提供一个实现.(当你销毁从它派生的任何类的实例时,无论基类析构函数是否被声明为纯虚拟,虚拟或非虚拟,都将始终使用基类析构函数.)这纯粹是一个C++语言实现细节.这并不意味着你的基类不是一个"接口",如果你有一个接口类,那么很可能在任何情况下析构函数的实现都是空的 - 你没有成员或基类会员担心.
如果你的接口至少有一些纯虚函数,那么将析构函数标记为纯函数没有任何实际价值,你的接口类已经是一个抽象类.派生类析构函数在技术上不会覆盖基类析构函数,因此您不需要派生类来提供用户声明的析构函数或类似的东西.
将析构函数声明为纯虚拟对象也会使您无法在类定义中内联提供析构函数的定义,尽管这是一个小细节.
"接口是任何只有纯虚函数的类"
- C++中的概念称为抽象类.抽象类是一个至少有一个纯虚函数的类.它不要求它的所有成员函数都是纯虚拟的.您无法实例化任何抽象类.
"这意味着如果你为你的接口定义了一个虚拟析构函数,那么你就不再拥有一个接口(只是一些抽象的基类).这只是滥用语言吗?我能理解发生了什么吗?"
- 相反,您必须为析构函数提供定义,即使它是纯虚拟的,因为析构函数总是在继承层次结构中以向下的方式调用.
标准 12.4:
析构函数可以声明为虚拟(10.3)或纯虚拟(10.4); 如果在程序中创建了该类或任何派生类的任何对象,则应定义析构函数.
例:
class A
{
public:
// this is stil a pure virtual function
// when there is a definition
virtual ~A() = 0;
};
class B: public A
{};
int main()
{
// fail to link due to missing definition of A::~A()
B b;
}
Run Code Online (Sandbox Code Playgroud)