C++笔记(七):C++继承

继承

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这个类中,有访问属性为publiceat这个方法。
在继承时,我们可以设置继承属性,使基类的数据成员在派生类中有不同的访问属性。
在这里插入图片描述
一个派生类继承了所有的基类方法,但下列情况除外:

  • 基类的构造函数、析构函数和拷贝构造函数;
  • 基类的重载运算符;
  • 基类的友元函数;
多继承

一个派生类可以由多个基类继承而来;
例:

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;
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值