c++基本语法学习2 继承 多态 模板

来源:互联网 发布:淘宝旺旺官方下载 编辑:程序博客网 时间:2024/04/29 18:09

  • 继承
    • 前言
    • 父类变量访问权限
    • 指定调用父亲的构造方法
    • 多继承
    • 虚继承
    • 继承方式
    • 继承方式
    • 函数模板

继承

前言:

  • 和java一样c++同样有继承不过是多继承

  • 继承样式如下

  • class B : [继承方式] [继承类名]

  • [继承方式]:

    1. public
    2. protected
    3. private

继承方式不写默认是private,继承方式最要影响的是孙子类,不写继承方式默认是private 后面详细解释

父类变量访问权限

我们知道一个类内部属性的访问修饰符有三种(java有四种)
分别对应如下:
1. proteced:如果不考虑继承的话权限是和private一样的,外部无法访问,但不同的是它修饰的属性时,属性可以被派生类继承
2. privat: 无法被继承也无法被外部访问
3. public: 允许外部访问和继承

修饰符 外部访问 继承 proteced 不允许 允许 private 不允许 不允许 public 允许 允许
  • 案例
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<iostream>#include<string.h>#include<stdlib.h>#include <stdio.h>#include <stdarg.h>using namespace std ;#include"test.h"//父亲类class Animal{private :    char* parent = "父亲";protected:    char *name = "动物名字";public:    void run(){        cout<<"我是动物正在跑"<<endl;    }    Animal(){        cout<<"Animal-->>空参数构造方法"<<endl;    }    char * weight;};//派生类class Dog : public Animal{public :    void run(){        //修改父亲的protected属性        name ="dog";        //访问父亲的name输出并且输出        cout<<"修改父亲属性后输出:"<<Animal::name<<endl;        //访问public属性        Animal::weight ="32";        //访问私有属性 编译报错//      Animal::parent ="test";        //调用父亲的run方法        Animal::run();        //打印        cout<<"我是dog正在跑" <<endl;    }    Dog(){        cout<<"Dog-->>空参数构造方法"<<endl;    }};int main(){    Dog* dog =  new Dog();    dog->run();    return 0;}
  • 输出:
    Animal–>>空参数构造方法
    Dog–>>空参数构造方法
    修改父亲属性后输出:dog
    我是动物正在跑
    我是dog正在跑

指定调用父亲的构造方法

c++和java会自动调用父亲的无参构造方法,那么我们指定一个构造方法的时候java可以用super关键字,那么c++呢?

class B{ public B(参数1类型 A,参数2类型 B){ }}class A:public B{    public:    //调用父亲的对应构造    A(参数1类型 A,参数2类型 B,参数3类型 C):B(A,B){    }}
  • 具体案例:
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<iostream>#include<string.h>#include<stdlib.h>#include <stdio.h>#include <stdarg.h>using namespace std ;#include"test.h"//父亲类class Animal{private :    char* parent = "父亲";protected:    char *name = "动物名字";public:    void run(){        cout<<"我是动物正在跑"<<endl;    }    Animal(){        cout<<"Animal-->>空参数构造方法"<<endl;    }    Animal(char * name,char * weight,char*parent){        cout<<"Animal-->>有参数构造方法"<<endl;    }    char * weight;};//派生类class Dog : public Animal{public :    void run(){        //修改父亲的protected属性        name ="dog";        //访问父亲的name输出并且输出        cout<<"修改父亲属性后输出:"<<Animal::name<<endl;        //访问public属性        Animal::weight ="32";        //访问私有属性 编译报错//      Animal::parent ="test";        //调用父亲的run方法        Animal::run();        //打印        cout<<"我是dog正在跑" <<endl;    }    Dog():Animal("dog","32","嘿嘿"){        cout<<"Dog-->>空参数构造方法"<<endl;    }};int main(){    Dog* dog =  new Dog();    dog->run();    return 0;}

输出:
Animal–>>有参数构造方法
Dog–>>空参数构造方法
修改父亲属性后输出:dog
我是动物正在跑
我是dog正在跑

  • tip: 这个还可以初始化指定属性哦
    如:
class A{    public:    int a;    A(int a):a(a){    }};int main(){    A *a = new A(3);    cout<<a->a<<endl;    return 0;}

结果:
输出3

多继承

一个人既可以是老师又可以是父亲,但他们的属性冲突了怎么办?

#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<iostream>#include<string.h>#include<stdlib.h>#include <stdio.h>#include <stdarg.h>using namespace std ;#include"test.h"class teacher{public:    char * work_name;    void work(){        cout<<work_name<<"  我是老师我正在教书"<<endl;    }    teacher(char * work_name){        this->work_name = work_name;    }};class father{public:    char * work_name;    void work(){        cout<<work_name<<"  我是父亲我正在带孩子"<<endl;    }    father(char * work_name){        this->work_name = work_name;    }};class xiao_ming:public father,public teacher{public:    xiao_ming():father("父亲"),teacher("老师"){        //存在二异性编译失败//      work_name="asd";        father::work_name = "我的职场 是父亲";    }};int main(){    xiao_ming* a = new xiao_ming();    a->father::work();    a->teacher::work();    return 0;}

虚继承

我们来看以下一个场景
这里写图片描述

B和c都继承A,然后D在继承B和C,此时有两个A实例变量导致了不明白到底使用哪个A

案例代码:

#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<iostream>#include<string.h>#include<stdlib.h>#include <stdio.h>#include <stdarg.h>using namespace std ;#include"test.h"class A{public:    int a;    A(){        cout<<"A的构造方法"<<endl;    }};class B:  public A{public:    int b;    B(){        cout<<"B的构造方法"<<endl;    }};class C:  public A{public:    int c;    C(){        cout<<"C的构造方法"<<endl;    }};class D:public B,public C{public :    int name;    D(){        cout<<"D的构造方法"<<endl;    }};int main(){    D d = D ();    return 0;}

输出:

A的构造方法B的构造方法A的构造方法C的构造方法D的构造方法

可见A对象被创建了两次

虚函数具体实现:

#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<iostream>#include<string.h>#include<stdlib.h>#include <stdio.h>#include <stdarg.h>using namespace std ;#include"test.h"class A{public:    int a;    A(){        cout<<"A的构造方法"<<endl;    }};class B: virtual public A{public:    int b;    B(){        cout<<"B的构造方法"<<endl;    }};class C:virtual  public A{public:    int c;    C(){        cout<<"C的构造方法"<<endl;    }};class D:public B,public C{public :    int name;    D(){        cout<<"D的构造方法"<<endl;    }};int main(){    D d = D ();    return 0;}

输出:

A的构造方法B的构造方法C的构造方法D的构造方法

可见调用了虚函继承之后,对象A只有被创建一次 被B和C共享

在看一下构造函数的问题

#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<iostream>#include<string.h>#include<stdlib.h>#include <stdio.h>#include <stdarg.h>using namespace std ;#include"test.h"class A{public:    int a;    A(int a){        this->a=a;        cout<<"A的构造方法"<<endl;    }};class B: virtual public A{public:    int b;    B(int b):A(1){        this->b = b;        cout<<"B的构造方法"<<endl;    }};class C:virtual  public A{public:    int c;    C(int c):A(2){        this->c =c;        cout<<"C的构造方法"<<endl;    }};class D:public B,public C{public :    int name;    D():B(22),C(33),A(33){        cout<<"D的构造方法"<<endl;    }};int main(){    D d = D ();    cout<<d.a<<endl;    return 0;}

继承方式

  • class B : [继承方式] [继承类名]

  • [继承方式]:

    1. public
    2. protected
    3. private

我们来看看三种继承方法:


大家可以参看这里

继承方式

参考文献

函数模板

#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<iostream>#include<string.h>#include<stdlib.h>#include <stdio.h>#include <stdarg.h>using namespace std ;#include"test.h"template <typename T,typename Y>T test(Y y){    return y;}template <typename T,typename Y>class person{public:        T t;        Y y;        person(T t){            this ->t =t;        }};int main(){    float a = test<int,float>(1);    cout<<a<<endl;    person<int,char> p(1);    return 0;}
0 0
原创粉丝点击