继承类型
当一个类派生自基类,该基类可以被继承为 public,protected或 private 几种类型。
我们几乎不使用 protected 或 private 继承,通常使用 public 继承。当使用不同类型的继承时,遵循以下几个规则:
公有继承(public):当一个类派生自公有基类时,基类的公有成员也是派生类的公有成员,基类的保护成员也是派生类的保护成员,基类的私有成员不能直接被派生类访问,但是可以通过调用基类的公有和保护成员来访问。
保护继承(protected): 当一个类派生自保护基类时,基类的公有和保护成员将成为派生类的保护成员。
私有继承(private):当一个类派生自私有基类时,基类的公有和保护成员将成为派生类的私有成员。
以下例子是基类public的派生,但同时会出现一些问题,理论上Shape指针保存了shape1,shape2类型的p和q,两次Shape->area()执行后应输出打印shape1_area()shape2_area(),但却打印了两次shape_area(),
#include <iostream>
using namespace std;
class shape
{
public:
shape(int a, int b)
{
r = a;
c = b;
}
int area();
protected:
int r, c;
};
class shape1 :public shape
{
public:
shape1(int a, int b) :shape(a, b) {};
int area();
};
class shape2 :public shape
{
public:
int area();
shape2(int a, int b) :shape(a, b) {};
};
int main()
{
shape1 p(1, 2);
shape2 q(2, 3);
shape* Shape;
Shape = &p;
Shape->area();
cout << "\n";
Shape = &q;
Shape->area();
return 0;
}
int shape::area()
{
cout << "shape_area()";
return 0;
}
int shape1::area()
{
cout << "shape1_area()";
return r * c;
}
int shape2::area()
{
cout << "shape2_area()";
return r * c * 2;
}
这是因为所谓的静态多态,或静态链接 - 函数调用在程序执行前就准备好了。有时候这也被称为早绑定,因为 area() 函数在程序编译期间就已经设置好了。
解决办法:在shape基类中area()函数前加上 virtual(虚拟)关键字
virtual int area()
{
cout << "shape_area()";
return 0;
}
使area()函数变成 虚函数,当我们不想在类里实现函数时 声明可以这么写使area()变成纯虚函数,外部实现照常不变
virtual int area()=0;
正确全部代码实现
#include <iostream>
using namespace std;
class shape
{
public:
shape(int a, int b)
{
r = a;
c = b;
}
virtual int area();
protected:
int r, c;
};
class shape1 :public shape
{
public:
shape1(int a, int b) :shape(a, b) {};
int area();
};
class shape2 :public shape
{
public:
int area();
shape2(int a, int b) :shape(a, b) {};
};
int main()
{
shape1 p(1, 2);
shape2 q(2, 3);
shape* Shape;
Shape = &p;
Shape->area();
cout << "\n";
Shape = &q;
Shape->area();
return 0;
}
int shape::area()
{
cout << "shape_area()";
return 0;
}
int shape1::area()
{
cout << "shape1_area()";
return r * c;
}
int shape2::area()
{
cout << "shape2_area()";
return r * c * 2;
}