您的位置:首页 > 编程语言 > C语言/C++

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

2017-04-28 14:38 453 查看
继承
前言

父类变量访问权限

指定调用父亲的构造方法

多继承

虚继承

继承方式

继承方式

函数模板

继承

前言:

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

继承样式如下

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

[继承方式]:

public

protected

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 : [继承方式] [继承类名]

[继承方式]:

public

protected

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: