目录
1,可见性
可见性关键字用来修饰成员(成员变量和成员函数)的可见性,默认是private
public是公开的,所有地方都可以访问,private是私有的,只有自己可以访问。
派生类会继承基类的public成员,但不继承private成员。
基类的成员如果用protected修饰,那么派生类就可以继承,别的地方不能访问。
示例:
#include<iostream>
using namespace std;
class B
{
public:
int i;
B()
{
i = 1, j = 2, k = 3;
}
friend void display2();
protected:
int j;
private:
int k;
};
class A :public B
{
public:
void display()
{
cout << i << endl;
cout << j << endl;
//cout << k << endl; //不能访问
}
};
void display2()
{
A a;
cout << a.i << endl;
cout << a.j << endl;
cout << a.k << endl;
}
int main()
{
A a;
a.display();
cout << a.i << endl;
//cout << a.j << endl; //不能访问
//cout << a.k << endl; //不能访问
display2();
return 0;
}
输出结果:
1
2
1
1
2
3
2,面向对象三大特性
封装,继承,多态
抽象就是将类的实现和使用分离开来。
封装就是类的使用不需要了解实现的细节。
3,继承
三种继承方式:
基类成员权限 | public继承 | private继承 | protected继承 |
---|---|---|---|
public | public | private | protected |
private | / | / | / |
protected | protected | private | protected |
public继承:子类可以访问父类的public成员和protected成员,继承后的属性不变
private继承:子类不能访问父类任何成员
protected继承:子类可以访问父类的public成员和protected成员,继承后的属性都是protected
默认是private继承。
class A: B{
}
class A: private B{
}
class A: public B{
}
4,派生类的构造函数和析构函数
派生类并不继承基类的构造函数,而是在自己的构造函数中调用基类的构造函数来初始化基类的数据域。
派生类的构造函数中如果没有显式调用基类的构造函数,就会调用基类的无实参构造函数。
如果要把一个类设计为拓展类,最好设计一个无实参的构造函数,以避免编程错误。
只能在类的实现中调用基类的构造函数,而不能在类的声明中调用。
同样,派生类更不可能继承基类的析构函数。
构造函数链:派生类的构造函数先调用基类的构造函数,再初始化其他成员。
析构函数链:派生类的析构函数先释放其他成员,再调用基类的析构函数。
示例:
#include<iostream>
using namespace std;
class Person
{
public:
Person()
{
cout << "Person构造函数" << endl;
}
~Person()
{
cout << "Person析构函数" << endl;
}
};
class Employee:public Person
{
public:
Employee()
{
cout << "Employee构造函数" << endl;
}
~Employee()
{
cout << "Employee析构函数" << endl;
}
};
class Fac :public Employee
{
public:
Fac()
{
cout << "Fac构造函数" << endl;
}
~Fac()
{
cout << "Fac析构函数" << endl;
}
};
int main()
{
Fac fac;
return 0;
}
结果:
Person构造函数
Employee构造函数
Fac构造函数
Fac析构函数
Employee析构函数
Person析构函数
5,友元函数和友元类
一个类中,friend关键字可以声明友元函数和友元类,被声明为友元的可以访问这个类的私有成员
(1)友元函数
#include <iostream>
using namespace std;
class MyClass
{
int x,y;
friend int f();
MyClass()
{
x=1,y=2;
}
};
int f()
{
MyClass s;
cout<<s.x;
}
int main() {
f();
return 0;
}
(2)友元类
#include <iostream>
using namespace std;
class A;
class MyClass
{
int x,y;
friend A;
MyClass()
{
x=1,y=2;
}
};
class A{
public:
int f()
{
MyClass s;
cout<<s.x;
}
};
int main() {
A a;
a.f();
return 0;
}
6,泛型继承
又是泛型,又是继承,这个知识点真是把c++的2个加都给结合起来了。
如果只是简单是把2个知识拼凑起来,写出来的代码是这样的:
template<typename T>
class A
{
protected:
int x=5;
};
template<typename T>
class B :public A<T>
{
public:
T get() {
return x;
}
};
然而这个是编译失败的,因为子类找不到符号x
正确代码:
template<typename T>
class A
{
protected:
int x=5;
};
template<typename T>
class B :public A<T>
{
public:
T get() {
return A<T>::x;
}
};