国家建设网站,杭州做网站比较好的公司,沈阳医大男科怎么样,故事式软文范例100字多态按字面的意思就是多种形态。当类之间存在层次结构#xff0c;并且类之间是通过继承关联时#xff0c;就会用到多态。C 多态意味着调用成员函数时#xff0c;会根据调用函数的对象的类型来执行不同的函数。1、纯虚函数声明如下#xff1a; virtual void funtion1()0; 纯…多态按字面的意思就是多种形态。当类之间存在层次结构并且类之间是通过继承关联时就会用到多态。C 多态意味着调用成员函数时会根据调用函数的对象的类型来执行不同的函数。1、纯虚函数声明如下 virtual void funtion1()0; 纯虚函数一定没有定义纯虚函数用来规范派生类的行为即接口。包含纯虚函数的类是抽象类抽象类不能定义实例但可以声明指向实现该抽象类的具体类的指针或引用。2、虚函数声明如下virtual ReturnType FunctionName(Parameter) 虚函数必须实现如果不实现编译器将报错错误提示为error LNK****: unresolved external symbol public: virtual void __thiscall ClassName::virtualFunctionName(void)3、对于虚函数来说父类和子类都有各自的版本。由多态方式调用的时候动态绑定。4、实现了纯虚函数的子类该纯虚函数在子类中就变成了虚函数子类的子类即孙子类可以覆盖该虚函数由多态方式调用的时候动态绑定。5、虚函数是C中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数。6、在有动态分配堆上内存的时候析构函数必须是虚函数但没有必要是纯虚的。7、友元不是成员函数只有成员函数才可以是虚拟的因此友元不能是虚拟函数。但可以通过让友元函数调用虚拟成员函数来解决友元的虚拟问题。8、析构函数应当是虚函数将调用相应对象类型的析构函数因此如果指针指向的是子类对象将调用子类的析构函数然后自动调用基类的析构函数。C多态意味着调用成员函数时会根据调用函数的对象的类型来执行不同的函数形成多态必须具备三个条件1、必须存在继承关系2、继承关系必须有同名虚函数其中虚函数是在基类中使用关键字Virtual声明的函数在派生类中重新定义基类中定义的虚函数时会告诉编译器不要静态链接到该函数存在基类类型的指针或者引用通过该指针或引用调用虚函数动态联编的实现机制 VTABLE编译器对每个包含虚函数的类创建一个虚函数表VTABLE表中每一项指向一个虚函数的地址即VTABLE表可以看成一个函数指针的数组每个虚函数的入口地址就是这个数组的一个元素。每个含有虚函数的类都有各自的一张虚函数表VTABLE。每个派生类的VTABLE继承了它各个基类的VTABLE如果基类VTABLE中包含某一项虚函数的入口地址则其派生类的VTABLE中也将包含同样的一项但是两项的值可能不同。如果派生类中重载了该项对应的虚函数则派生类VTABLE的该项指向重载后的虚函数如果派生类中没有对该项对应的虚函数进行重新定义则使用基类的这个虚函数地址。在创建含有虚函数的类的对象的时候编译器会在每个对象的内存布局中增加一个vptr指针项该指针指向本类的VTABLE。在通过指向基类对象的指针设为bp调用一个虚函数时编译器生成的代码是先获取所指对象的vtb1指针然后调用vtb1所指向类的VTABLE中的对应项具体虚函数的入口地址。当基类中没有定义虚函数时其长度数据成员长度派生类长度自身数据成员长度基类继承的数据成员长度当基类中定义虚函数后其长度数据成员长度虚函数表的地址长度派生类长度自身数据成员长度基类继承的数据成员长度虚函数表的地址长度。包含一个虚函数和几个虚函数的类的长度增量为0。含有虚函数的类只是增加了一个指针用于存储虚函数表的首地址。派生类与基类同名的虚函数在VTABLE中有相同的索引号或序号。虚函数这里说的有些乱因为 C 写法奇葩略多。其实可以简单理解。虚函数可以不实现定义。不实现定义的虚函数是纯虚函数。在一个类中如果存在未定义的虚函数那么不能直接使用该类的实例可以理解因为未定义 virtual 函数其类是抽象的无法实例化。将报错误undefined reference to vtable for xxx这和其它语言的抽象类抽象方法是类似的——我们必须实现抽象类否则无法实例化。virtual 和 abstract还是有些区别的也就是说如果存在以下代码using namespace std;class Base {
public:virtual void tall();
};class People : Base {
public:void tall() {cout people endl;};
};那么在 main 方法中我们不能使用 Base base; 这行代码此时的 tall 没有实现函数表vtable的引用是未定义的故而无法执行。但我们可以使用 People people; 然后 people.tall(); 或 (people)-tall(); 因为People实现或者说重写、覆盖了 Base 的纯虚方法 tall()使其在 People 类中有了定义函数表挂上去了于是可以诞生实例了。int main() {
// Base base;//不可用People people;//可用people.tall();(people)-tall();return 0;上述的是针对虚函数而言普通的函数即使我们只声明不定义也不会产生上述不可用的问题。父类的虚函数或纯虚函数在子类中依然是虚函数。有时我们并不希望父类的某个函数在子类中被重写在 C11 及以后可以用关键字 final 来避免该函数再次被重写。例#includeiostream
using namespace std;
class Base
{public:virtual void func(){coutThis is Baseendl;}
};
class _Base:public Base
{public:void func() final//正确func在Base中是虚函数{coutThis is _Baseendl;}
};
class __Base:public _Base
{
/* public://不正确func在_Base中已经不再是虚函数不能再被重写void func(){coutThis is __Baseendl;}*/
};
int main()
{_Base a;__Base b;Base* ptra;ptr-func();ptrb;_Base* ptr2b; ptr-func();ptr2-func();
}以上程序运行结果This is _Base
This is _Base
This is _Base如果不希望一个类被继承也可以使用 final 关键字。格式如下class Class_name final
{...
};则该类将不能被继承。