Day1:一句话说透:
权限总结:
- 父亲的隐私儿子不能知道
<cout << wife << end; //错!> - 他让你知道什么你就知道什么
<cout << getwife()<<endl; >
C++类继承和派生类
- 什么是继承?
- 继承就是子类一开始就包含了 父类的属性
- 继承的写法
#include<iostream>
#include<string>
class father {
public:
protected:
private:
};
class son1 :public father {// a total of inheritance
public:
protected:
};
class son2 :protected father {// protected the inheritance
public:
protected:
};
class son3 :private father {// private inheritance
public:
protected:
};
int main()
{
father fr;
son1 s1;
return 0;
}
权限:
- 继承方式只会增强父类属性在子类中的权限显示
#include<iostream>
#include<string>
using namespace std;
class father {
public:
int a1=01;
void print()
{
cout << name << "father\t" << money << endl;
}
// 提供接口访问私有
string getwife()
{
return wife;
}
protected:
int a2=02;
string name="F";
int money=100000;
private:
int a3=03;
string wife = "securet\n";
};
class son1 :public father {// a total of inheritance
public:
void print()
{
//print(); ? why it is wrong in my IDE?
cout << name << "Son \t" << money << endl;
//cout << wife << end; 父亲的隐私儿子不能知道
cout << getwife()<<endl;
}
protected:
private:
};
class son2 :protected father {// protected the inheritance
public:
void print() {
cout << name << " protected " << money << endl;// 保护属性
}
int num1 = 100;
protected:
//int num2 = 100; 补课直接访问
private:
};
class son3 :private father {// private inheritance
public:
void print()
{
cout << name << " privated\t" << money << endl;
cout << a1 << '\t' << a2 << '\t'<< endl;//a3 私有 不可访问
}
protected:
};
int main()
{
father fr;
fr.print();
fr.a1;// a2 a3 不可再类外属性 ,类内可以
son1 s1;
s1.a1; // 共有属性
// 不可访问s1.a2 a3
s1.print();
son2 s2;
// 保护继承 a1 a 2a3 都不能访问
cout << s2.num1 << endl;
s2.print();
son3 s3;
// a 123都不能访问
s3.print();
return 0;
}
- 私有继承用于绝种 父类
- 不想要产生孙子类时 就要用私有继承
继承中的构造函数
-
父类的属性通过父类的构造函数初始化
-
子类中的构造函数,必须要调用父类构造函数,必须采用初始化参数列表的方式
-
单继承和多继承:
- 单继承: 只有一个父类
- 多继承: 两个或者两个以上的父类
-
继承的属性,无论被继承多少次,所以类一般不会被继承很多层,会导致类的臃肿
-
- 单继承
#include<iostream>
#include<string>
using namespace std;
class Parent {
public:
Parent(string Fname,string Sname):Fname(Fname),Sname(Sname){}
Parent() { cout << "父类无参构造函数" << endl; };
protected:
string Fname;
string Sname;
private:
};
class son : public Parent {
public:
son() { cout << "这是子类无惨构造函数,优先调用父类无惨构造函数" << endl; }// 要这样写 父类必有 缺省或者无参构造
// 子类构造函数
//父类属性必须调用父类构造函数并用初始化参数列表初始化
son(string Fname, string Sname, string sonSname):Parent(Fname,Sname)
{
// 自己属性咋初始化都可以
this->sonFname = Fname;
this->sonSname = sonSname;
}
void print()
{
cout << "Father:" << Fname + Sname << endl;
cout << "SOn :" << sonFname + sonSname << endl;
}
protected:
string sonFname;
string sonSname;
};
int main()
{
son s{"白","江江","慕慕"/*son name*/};
s.print();
return 0;
}
多继承:
// 有无参构造 !无父类的必须调用 父类构造函数 并且用初始化参数列表
#include<iostream>
#include<string>
using namespace std;
//多继承
//欧阳
//多吉
//欧多阳吉
class MM {
public:
//MM() { cout << "MM的无参构造函数 " << endl; }
MM(string Fmmname, string Smmname) {
this->Fmmname = Fmmname;
this->Smmname = Smmname;
}
protected:
string Fmmname;
string Smmname;
};
class GG{
public:
//GG() { cout << "GG的无参构造函数 " << endl; }
GG(string Fggname, string Sggname)
{
this->Fggname = Fggname;
this->Sggname = Sggname;
}
protected:
string Fggname;
string Sggname;
};
// class child
class Girl:public MM,public GG{
public:
//Girl(){}// ALL 父类也得有无参数构造函数
// 有无参构造可以在下面不初始化 父类,一般需要
// 子类的可以直接初始化
//Girl(string Fggname, string Sggname,string Fmmname,string Smmname) {
// this->Fgname = Fggname+Fmmname;
// this->Sgname = Sggname+Smmname;
//}
// 有无参构造 !无父类的必须调用 父类构造函数 并且用初始化参数列表
Girl(string Fggname, string Sggname, string Fmmname, string Smmname)
:MM(Fmmname, Smmname), GG(Fggname, Sggname)
{
this->Fgname = Fggname+Fmmname;
this->Sgname = Sggname+Smmname;
}
// 给方法打印 孩子
void print()
{
cout << "父亲:"<<Fggname + Sggname << endl;
cout << "母亲:"<<Fmmname + Smmname << endl;
cout << "女儿:"<<Fgname + Sgname << endl;
}
protected:
string Fgname;
string Sgname;
};
int main()
{
//欧阳
//多吉
//欧多阳吉
Girl girl("欧", "阳", "多", "吉");
girl.print();
return 0;
}
经验:各位 张三给孩子起名好听一点,
名字不要太短;
数据成员同名
- 成员函数名同名
类内 不做特别处理OR this,就近原则
类名限定 - 正常赋值调用
- 非正常赋值调用
#include <iostream>
using namespace std;
class M
{
public:
M(string name, int age) :name(name), age(age) {}
void print()
{
cout << "M:";
cout << name << "\t" << age << endl;
}
protected:
string name;
int age;
};
class Girl :public M
{
public:
// 同名了 父类 指定了参数, 子类初始化参数列表 传参
Girl(string name, int age) :M("父类", 28), name(name), age(age) {}
void print()
{
//不做特别处理,就近原则
cout << name << "\t" << age << endl;
//类名限定
cout << M::name << "\t" << M::age << endl;
//不做特别处理,就近原则
M::print();// print HUIDIGUI
}
protected:
string name;
int age;
};
int main()
{
//不做特别处理,就近原则
//正常对象调用
Girl girl("girl", 18);// 子类调用子类方法
girl.print();
M m("mm", 28);
m.print();
//正常的指针调用
//就近原则
Girl* pG = new Girl("newGirl", 19);
pG->print();
pG->M::print();// 类名指定访问OK
M* pM = new M("newM", 29);
pM->print();
//非正常的指针
//1.允许子类对象初始化父类指针
M* pMM = new Girl("newGirl", 49);
pMM->print(); //父类的
//在没有virtual情况下,看指针类型
//在有virtual情况,看赋值对象
//2.父类对象初始化子类指针,不安全
//Girl* pGirl = new MM("newMM", 29); 错误
//Girl* pGirl = (Girl*)pM;
//pGirl->print(); 引发
return 0;
}
####### 贴代码
虚继承:---->菱形继承
//虚继承 --->菱形继承
#include <iostream>
using namespace std;
//虚继承 --->菱形继承
class A
{
public:
A(int a) :a(a) {}
protected:
int a;
};
class B :virtual public A
{
public:
B(int a, int b) :A(a), b(b) {}
protected:
int b;
};
class C :virtual public A
{
public:
C(int a, int c) :A(a), c(c) {}
void printC()
{
cout << a << endl;
}
protected:
int c;
};
class D :public C, public B
{
public:
//菱形继承,必须调用祖父的构造函数
D() :B(1, 2), C(3, 4), A(999)
{
}
void print()
{
//只有一个a 只有一份
cout << a << endl;
cout << B::a << endl;
cout << C::a << endl;
printC();
}
protected:
};
int main()
{
D d;
d.print();
0;
}
总结
- 构造 顺序:
- 因为子类在父类基础上构建,所以需要有 父类 构造才能 构造子类构造函数
+析构顺序:
计算机里拆房子要遵循流程,一步一步拆;
从 屋顶(子类)开始拆
- 因为子类在父类基础上构建,所以需要有 父类 构造才能 构造子类构造函数
子类对象初始化父类指针:
对象:比作财富
类 :比作需求思想
+ 子类财富可以满足 父类
父类对不能象初始化子类指针:
(有专门的方法后面将《可以说说思想教育》)
+ 父辈财富不能完全满足青年,所以我们要努力
————————人生苦短,我看看美女