class A{};
class B : public A {};
class Person {
public:
virtual A* f() {return new A;}
};
class Student : public Person {
public:
virtual B* f() {return new B;}
};
// 一个类不能被继承
//class Car
// C++11的方法: final修饰的类叫最终类,不能继承
class Car final
{
public:
private:
// C++98的方法:父类的构造函数私有
// 子类的构造无法生成和实现,导致子类对象无法实例化
Car()
{}
};
class Benz :public Car
{
public:
};
2. override: 检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错。
重载、覆盖**(重写)、隐藏(重定义)**的对比
多态的原理
虚函数表
通过观察测试我们发现 b 对象是 8bytes , 除了_b成员,还多一个__vfptr放在对象的前面(注意有些平台可能会放到对象的最后面,这个跟平台有关),对象中的这个指针我们叫做虚函数表指针(v代表virtual,f代表function) 。一个含有虚函数的类中都至少都有一个虚函数表指针,因为虚函数的地址要被放到虚函数表中,虚函数表也简称虚表。
// 针对上面的代码我们做出以下改造
// 1. 我们增加一个派生类 Derive 去继承 Base
// 2.Derive 中重写 Func1
// 3.Base 再增加一个虚函数 Func2 和一个普通函数 Func3
class Base
{
public :
virtual void Func1 ()
{
cout << "Base::Func1()" << endl ;
}
virtual void Func2 ()
{
cout << "Base::Func2()" << endl ;
}
void Func3 ()
{
cout << "Base::Func3()" << endl ;
}
private :
int _b = 1 ;
};
class Derive : public Base
{
public :
virtual void Func1 ()
{
cout << "Derive::Func1()" << endl ;
}
private :
int _d = 2 ;
};
int main ()
{
Base b ;
Derive d ;
return 0 ;
}
派生类对象 d 中也有一个虚表指针, d 对象由两部分构成,一部分是父类继承下来的成员,虚表指针也就是存在部分的另一部分是自己的成员。
基类 b 对象和派生类 d 对象虚表是不一样的,这里我们发现 Func1完成了重写,所以d的虚表中存的是重写的Derive::Func1,所以虚函数的重写也叫作覆盖 ,覆盖就是指虚表中虚函数的覆盖。重写是语法的叫法,覆盖是原理层的叫法。
1.以下程序输出结果是什么()
class A
{
public :
virtual void func ( int val = 1 ){ std::cout << "A->" << val << std::endl ;}
virtual void test (){ func ();}
};
class B : public A
{
public :
void func ( int val = 0 ){ std::cout << "B->" << val << std::endl ; }
};
int main ( int argc , char* argv [])
{
B * p = new B ;
p -> test ();
return 0 ;
}
A: A->0 B: B->1 C: A->1 D: B->0 E: 编译出错 F: 以上都不正确
答案:B
2.多继承中指针偏移问题?下面说法正确的是( )
class Base1 { public : int _b1 ; };
class Base2 { public : int _b2 ; };
class Derive : public Base1 , public Base2 { public : int _d ; };
int main (){
Derive d ;
Base1 * p1 = & d ;
Base2 * p2 = & d ;
Derive * p3 = & d ;
return 0 ;
}
A : p1 == p2 == p3 B : p1 < p2 < p3 C : p1 == p3 != p2 D : p1 != p2 != p3
选C p1和p2的顺序是由Base1和Base2继承顺序决定的