1 类和类之间的关系
#include <iostream>
using namespace std;
class A
{
public:
void funcA()
{
cout << "funcA()" << endl;
}
};
// 1 包含关系 B has A
class B
{
public:
void funcB()
{
a.funcA();
}
A a;
};
//2 依赖关系 C use A
class C
{
public:
void funcB(A *a)
{
a->funcA();
}
};
//3 继承关系 D extend A
class D : public A
{
public:
void funcD()
{
//直接调用A类的方法
funcA();
}
};
int main(void){
D d;
d.funcA();
return 0;
}
执行结果
funcA()
funcA()
2 继承的访问方式
#include <iostream>
using namespace std;
class Parent
{
public:
int pub; // 类的内部和外部均可访问
public:
int pro; // 类的内部以及子类可以,外部不可以访问
private:
int pri; // 类的内部可以反问, 其他都不可访问
};
//1 类的公有继承
class Child1 : public Parent
{
void func()
{
pub = 0;
pro = 1;
//pri = 2; // Error:'pri' is a private member of 'Parent'
}
};
//2 类的保护继承
class Child2 : protected Parent
{
void func()
{
pub = 0; // 此时pub 变为 pro
pro = 1;
//pri = 2; // Error:'pri' is a private member of 'Parent'
}
};
//3 类的私有继承
class Child3 : private Parent
{
void func()
{
pub = 0; //4 父类的pub在此类中变为pri
pro = 1; //5 父类的pro在此类中变为pri
//pri = 2; // Error:'pri' is a private member of 'Parent'
}
};
class SubChild1 : public Child3
{
void func()
{
//pub = 1; //Error:'pub' is a private member of 'Parent'
//pro = 2; //Error:'pub' is a private member of 'Parent'
}
};
3 类的兼容性赋值原则
#include <iostream>
using namespace std;
class Parent
{
public:
void printP()
{
cout << "Parent printP()" << endl;
}
int a;
};
class Child : public Parent
{
public:
void printC()
{
cout << "Child printC()" << endl;
}
};
void print(Parent *p)
{
p->printP();
}
int main(void){
//1 子类对象可以当做父类对象使用
Child c;
c.printP();
c.a = 10;
//2 子类对象可以赋值给父类
Parent p = c;
p.printP();
//3 父类指针可以指向子类对象
Parent *pp = &c;
cout << "pp->a = " << pp->a << endl;
//4 不能用子类指针指向父类对象
//Child *cp = &p; //Error:Cannot initialize a variable of type 'Child *' with an rvalue of type 'Parent *'
//5 子类引用不可以引用父类对象
//Error:Non-const lvalue reference to type 'Child' cannot bind to a value of unrelated type 'Parent'
//Child &cr = p;
//6 父类引用可以引用子类对象
Parent &pr = c;
print(&p);
print(&c);
return 0;
}
执行结果
Parent printP()
Parent printP()
pp->a = 10
Parent printP()
Parent printP()
4 继承的构造和析构
#include <iostream>
using namespace std;
class Parent
{
public:
Parent(int a)
{
this->a = a;
cout << "Parent(int a)" << endl;
}
~Parent()
{
cout << "~Parent()" << endl;
}
void printA()
{
cout << "a = " << a << endl;
}
private:
int a;
};
class Son : public Parent
{
public:
Son(int a, int b) : Parent(a)
{
this->b = b;
cout << "Son(int a, int b)" << endl;
}
~Son()
{
cout << "~Son()" << endl;
}
void printB()
{
cout << "b= " << b << endl;
}
void printAB()
{
Parent::printA();
this->printB();
}
private:
int b;
char *name;
};
void test1()
{
//1 先执行父类的构造,在执行子类的构造,
//2 先执行子类的析构,在执行父类的析构
Son s(20, 20);
s.printAB();
}
int main(void){
test1();
return 0;
}
执行结果
Parent(int a)
Son(int a, int b)
a = 20
b= 20
~Son()
~Parent()
5父类和子类的成员变量重名
#include <iostream>
using namespace std;
class Parent
{
public:
Parent(int a)
{
this->a = a;
}
int a;
};
class Child : public Parent
{
public:
Child(int a, int a_p) : Parent(a_p)
{
this->a = a;
}
void print()
{
cout << "Child::a" << a << endl;
//1 如果想要访问父类中的重名字段需要加上父类的作用域
cout << "Parent :: a = " << Parent::a << endl;
}
int a;
};
int main(void){
Child c(10, 100);
c.print();
return 0;
}
Child::a10
Parent :: a100
6 派生类中的static
#include <iostream>
using namespace std;
class A
{
public:
static int s;
};
//1 静态成员变量要在类的外部初始化
int A::s = 10;
class B:public A
{
};
int main(void){
B b;
cout << "b.s = " << b.s << endl;
b.s = 100;
cout << "b.s = " << b.s << endl;
cout << "A::s = " << A::s << endl;
return 0;
}
执行结果
b.s = 10
b.s = 100
A::s = 100
7 多继承
#include <iostream>
using namespace std;
//家具
class Furniture
{
public:
int m;
};
//床
class Bed : public Furniture
{
public:
void sleep()
{
cout << "在床上睡觉" << endl;
}
};
//沙发
class Sofa : public Furniture
{
public:
void sit()
{
cout << "在沙发上睡觉" << endl;
}
};
//沙发床
class SofaBed : public Bed, public Sofa
{
public:
void sitAndSleep()
{
sit();
sleep();
}
};
int main(void){
Bed b;
b.sleep();
cout << "---------" << endl;
Sofa s;
s.m = 100;
s.sit();
cout << "---------" << endl;
SofaBed sb;
sb.sitAndSleep();
return 0;
}
执行结果
在床上睡觉
---------
在沙发上睡觉
---------
在沙发上睡觉
在床上睡觉
8 虚继承
依然是上面的例子,如果不采用虚继承
class Bed : public Furniture
class Sofa : public Furniture
由于Fureniture中有个m变量,所以Bed和Sofa同时拥有了变量m
class Furniture
{
public:
int m;
};
此时如果同时继承这两个类,则 Furniture 中的m则存在二义性,即不知道该继承那个类中的m
class SofaBed : public Bed, public Sofa
//二义性
//sb.m = 50; //Error: Non-static member 'm' found in multiple base-class subobjects of type 'Furniture':
解决方式: 采用虚继承,这样能让派生类中只产生一个子对象m
class Sofa : virtual public Furniture
class Bed : virtual public Furniture
//二义性--->通过虚继承解决
sb.m = 50;
cout << "sb.m = " << sb.m << endl;
执行结果
sb.m = 50