继承
C++中通过继承机制,可以利用已有的数据类型来定义新的数据类型。所定义的新的数据类型不仅拥有新定义的成员,而且还同时拥有旧的成员。这使得维护和创建一个应用程序变得比较容易。
基类&派生类
一个类可以派生自一个或多个基类。定义一个派生类,我们使用一个类派生列表来指定基类。形式如下:
class derived-class: access-specifier base-class
例:
class animal{
public:
animal() {
std::cout << "animal init" << std::endl;
}
~animal() {
std::cout << "~animal()" << std::endl;
}
public:
void eat() {
std::cout << "animal eat" << std::endl;
}
void sleep() {
std::cout << "animal sleep" << std::endl;
}
};
class Dog : public animal
{
private:
public:
Dog(){
std::cout << "Dog init" << std::endl;
}
~Dog(){
std::cout << "~Dog()" << std::endl;
}
};
int main(int argc, char* argv[])
{
Dog dog;
dog.eat();
printf("Hello World!\n");
return 0;
}
派生类的构造与析构
在构造Dog
这个类时,是如何去构造?
运行代码,得到以下结果:
animal init
Dog init
animal eat
Hello World!
~Dog()
~animal()
可以看到,在构造时,先构造基类,再去构造派生类;在析构时,先析构派生类,再去析构基类;那基类与派生类的数据形式是派生类包裹着基类。
在构造派生类时,可以调用特定的基类构造函数;在初始化列表中,进行定义;
Dog() : animal(){
}
访问控制和继承
上面还可以看到,我们在Dog
这个类中直接调用eat
这个方法。那说明在Dog
这个类中,有访问属性为public
的eat
这个方法。
在继承时,我们可以设置继承属性,使基类的数据成员在派生类中有不同的访问属性。
一个派生类继承了所有的基类方法,但下列情况除外:
- 基类的构造函数、析构函数和拷贝构造函数;
- 基类的重载运算符;
- 基类的友元函数;
多继承
一个派生类可以由多个基类继承而来;
例:
class A{
public:
A();
~A();
}
class B{
public:
B();
~B();
}
class C : public A ,public B
{
public:
C();
~C();
}
静态成员与继承
在基类中静态成员,都会继承给派生类;所有的派生类都会共享静态成员变量,某一处修改静态变量的值,就会就会修改派生类和基类中的值。
静态成员的访问属性跟继承方式有关,与普通成员相同;
#include <iostream>
class animal{
public:
animal() {
std::cout << "animal init" << std::endl;
}
~animal() {
std::cout << "~animal()" << std::endl;
}
protected:
void test(void){
std::cout << "animal :protected test " << std::endl;
}
public:
void eat() {
std::cout << "animal eat" << std::endl;
}
void sleep() {
std::cout << "animal sleep" << std::endl;
}
public:
static int a ;
void ShowA()
{
std::cout << a << std::endl;
}
static void ts(void)
{
std::cout << " ts"<< std::endl;
}
};
int animal::a = 100;
class Dog : public animal
{
private:
public:
Dog(){
std::cout << "Dog init" << std::endl;
}
~Dog(){
std::cout << "~Dog()" << std::endl;
}
public:
void Dog_test()
{
test();
}
void SetA(int val)
{
a = val;
}
};
class Cat : public animal
{
private:
public:
Cat();
~Cat();
};
Cat::Cat()
{
}
Cat::~Cat()
{
}
int main(int argc, char* argv[])
{
Dog dog;
Cat cat;
dog.eat();
cat.a = 10;
dog.ShowA();
Dog::ts();
printf("Hello World!\n");
return 0;
}
转换与继承
基类与派生类之间,可以进行转换。
派生类 -> 基类
- 可以通过指针、引用进行转换;
- 不能进行对象转换;
基类 -> 派生类
- 不能直接进行转换
- 只能进行强制转换基类指针
#include <iostream>
class Item_base{
public:
Item_base() {}
~Item_base() {}
int base;
};
class Bulk_item : public Item_base
{
public:
Bulk_item() {}
~Bulk_item() {}
int bulk;
};
int main(int argc, char* argv[])
{
std::cout << "hello c++ "<< std::endl;
Item_base item1;
Bulk_item item2;
Bulk_item *p = static_cast<Bulk_item *>(&item1);//强制转换基类指针
Item_base *item = &item2;
return 0;
}