c++属于面向对象的编程,主要特征有:
抽象;封装;继承;多态;
今天学习关于类的继承:
采用继承的场合:
1、当创建的新类与现有的类的属性相似,只是多出了若干属性,可以采用,减少代码的重复率
2、创建多个类,当多个类之间存在相同部分的属性特征,此时可以将共同属性特征提取,作为基类 (总是一切为了效率)
访问限制符:public;private;protected;
1.单继承
#include<iostream>
#include<string>
using namespace std;
class person {
public:
void setname(string name);
string getname();
private:
string name;
};
class teacher :public person
{
public:
void setschool(string school);
string getschool();
private:
string school;
};
int main()
{
teacher tr;
tr.setname("laoliu");
//tr.getname();
tr.setschool("jinchan");
//tr.getschool();
//cout << "helo" << endl;
cout << tr.getschool()<<"\n" << tr.getname() << endl;
return 0;
}
void person::setname(string name)
{
this->name = name;
}
string person::getname()
{
return string(name);
}
void teacher::setschool(string school)
{
this->school = school;
}
string teacher::getschool()
{
return string(school);
}
修改访问权限
using 关键字可修改基类成员中在派生类中的访问权限,如将public改为private 或者将protected该为public
注意:using只能改变基类中的public和protected成员的权限,不能修改private的权限
还有一个遮蔽问题
就是基类和派生类(也叫做子类和父类)
如果双方的成员中有相同的函数成员
派生类会遮蔽子类的而用自己的成员函数
不会有重载问题
在派生类中调用基类的构造函数
#include<iostream>
#include<string>
using namespace std;
class person {
public:
person(string name)
{
this->name = name;
}
protected:
string name;
};
class teacher :public person
{
public:
teacher(string school,string name):person(name)
{
this->school = school;
}
void show();
private:
string school;
};
int main()
{
teacher tr("jinsahn","xiaohua ");
tr.show();
return 0;
}
void teacher::show()
{
cout << this->name << this->school << endl;
}
注意事项
在派生类中,必须将基类的构造函数放在派生类的构造函数的尾部,显示调用,以到达初始化继承的成员变量。
1、完成对对象内存空间的开辟,会在调用构造函数的而同时自动完成
类本身不占用内存,而对象占用内存
2、派生类的成员必须通过派生类的构造函数进行初始化,而被继承的成员通过调用基类构造函数初始化即可
3、若派生类成员中存在const或者引用的时候,初始化必须通过成员列表初始化的方式完成
4、派生类和基类的构造函数执行的过程,是派生类的构造函数调用的基类的构造函数先被执行
2.多继承
只是师承多人的感觉
格式:
class 派生类名(参数表):派生方式1 基类名1,派生方式2 基类名2,…,派生方式n 基类名n
{
private:
新增私有成员列表;
public:
新增公开成员列表;
};
上练习代码
#include<iostream>
#include<string>
using namespace std;
class TestA
{
public:
TestA(int a, int b)
{
cout << "this is test a " << endl;
this->a = a;
this->b = b;
}
~TestA()
{
cout << "this is test a destructor";
}
void show()
{
cout << "a= " << a << " a=" << a << endl;
}
protected:
int a;
int b;
};
class TestB
{
public:
TestB(int c, int d)
{
cout << "this is test b " << endl;
this->c = c;
this->d = d;
}
~TestB()
{
cout << "this is test b destructor";
}
void show()
{
cout << "c= " << c << " d=" << d << endl;
}
protected:
int c;
int d;
};
class TestC:public TestA,public TestB
{
public:
TestC(int a,int b,int c,int d,int e, int f):TestA(a,b),TestB(c,d)
{
cout << "this is test C " << endl;
this->e = e;
this->f = f;
}
~TestC()
{
cout << "this is test C destructor";
}
void show()
{
cout
<<"a="<<a
<<" b="<<b
<<" c="<<c
<<" d="<<d
<<" e=" << e
<<" f=" << f
<< endl;
}
protected:
int e;
int f;
};
int main()
{
TestC ts(1, 2, 3, 4, 5, 6);
ts.show();
return 0;
}
其中可以看到构造函数和析构函数的调用顺序不同
3.菱形继承
直接上大佬的总结链接吧
c++中的菱形继承与虚拟菱形继承