一、公有继承
当继承方式为公有继承的时候,基类中不同的访问限定符下的数据成员和成员函数被继承到了派生类的不同的访问限定符下。
二、代码演示
用代码来验证上述的理论知识
创建Person类,数据成员:Name,Age 成员函数:构造函数、析构函数、eat()
创建Worker类,数据成员:Salary 成员函数:构造函数、析构函数、work()
1、在公有继承方式下,基类的数据成员和成员函数访问属性为public时,派生类从基类公有继承过来的成员访问属性应为什么?
person.h
#include<iostream>
#include<string>
using namespace std;
class Person
{
public:
Person();//构造
~Person();//析构
void eat();
string Name;
int Age;
};
person.cpp
#include"person.h"
Person::Person()
{
cout<<"Person()"<<endl;
}
Person::~Person()
{
cout<<"~Person()"<<endl;
}
void Person::eat()
{
cout<<"eat()"<<endl;
}
worker.h
#include"person.h"
class Worker:public Person//Worker类公有继承Person类
{
public:
Worker();
~Worker();
int Salary;
void work();
};
worker.cpp
#include"worker.h"
Worker::Worker()
{
cout<<"Worker()"<<endl;
}
Worker::~Worker()
{
cout<<"~Worker()"<<endl;
}
void Worker::work()
{
//Name = "v";
//Age = 18;
cout<<"work()"<<endl;
}
main.cpp
#include "Worker.h"
#include<stdlib.h>
using namespace std;
int main(void)
{
//从栈中实例化对象
Worker Worker;
Worker.Age = 18;
Worker.Name = "v";
Worker.Salary = 20;
Worker.eat();
Worker.work();
/*从堆中实例化对象
Worker *p = new Worker();
p->Age = 18;//用子类Worker实例化的对象p去访问父类Person的数据成员
p->Name = "v";
p->Salary = 20;
p->eat();//用子类Worker实例化的对象p去访问父类Person的数据成员
p->work();
delete p;
p = NULL;*/
return 0;
}
从栈中实例化对象 运行结果:
先构造基类Person类,再构造派生类Worker类;从运行结果看到派生类Worker可以正常访问到基类的eat()、Name、Age,说明在公有继承中,基类中public访问限定符下的数据成员和成员函数确实被继承到了派生类的public访问限定符下;析构的时候时先构造的后析构。
从堆中实例化对象 运行结果:
结论:无论是从堆上还是栈上实例化一个对象,在公有继承方式下,基类中public访问限定符下的数据成员和成员函数被继承到了派生类的public访问限定符下。
2、在公有继承方式下,基类的数据成员和成员函数访问属性分别为protectded和private时,派生类从基类公有继承过来的成员访问属性应该为什么?
将Person类中的数据成员分别改成protected和private
person.h
#include<iostream>
#include<string>
using namespace std;
class Person
{
public:
Person();
~Person();
void eat();
protected:
string Name;
private:
int Age;
};
person.cpp
#include"person.h"
Person::Person()
{
cout<<"Person()"<<endl;
}
Person::~Person()
{
cout<<"~Person()"<<endl;
}
void Person::eat()
{
Name = "v";
Age = 18;
cout<<Name<<endl;
cout<<Age<<endl;
cout<<"eat()"<<endl;
}
main.cpp
#include"person.h"
int main(void)
{
Person person;
//在protected和private下定义的数据成员,没有办法在main函数中使用外部实例化的对象进行访问
person.Age = 18;//erro
person.Name = "v";//erro
}
运行结果:
将Person类中的数据成员分别改成protected和private,在main函数中实例化一个person对象对数据成员进行访问,程序无法执行;说明在protected和private下定义的数据成员,没有办法在main函数中使用外部实例化的对象进行访问。
main.cpp
#include"person.h"
int main(void)
{
Person person;
//在protected和private下定义的数据成员,在成员函数中访问是可以的
person.eat();//ok
}
运行结果:
程序可以执行,在protected和private下定义的数据成员,用实例化的对象在成员函数中访问是可以的。
结论:在protected和private下定义的数据成员,没有办法在main函数中使用外部实例化的对象进行访问;但是可以在自己的成员函数中进行访问
将上述代码person类的数据成员分别改为protected和private
person.h
#include<iostream>
#include<string>
using namespace std;
class Person
{
public:
Person();
~Person();
void eat();
protected:
string Name;
private:
int Age;
};
person.cpp
#include"person.h"
Person::Person()
{
cout<<"Person()"<<endl;
}
Person::~Person()
{
cout<<"~Person()"<<endl;
}
void Person::eat()
{
cout<<"eat()"<<endl;
}
worker.h
#include"person.h"
class Worker:public Person
{
public:
Worker();
~Worker();
int Salary;
void work();
};
worker.cpp
#include"worker.h"
Worker::Worker()
{
cout<<"Worker()"<<endl;
}
Worker::~Worker()
{
cout<<"~Worker()"<<endl;
}
void Worker::work()
{
Name = "v";
Age = 18;
cout<<"work()"<<endl;
}
main.cpp
#include "Worker.h"
#include<stdlib.h>
using namespace std;
int main(void)
{
Worker worker;
worker.work();//erro
}
运行结果:
结论:在公有继承之后,父类的private下数据成员不会被继承到子类的private访问限定符下,虽然被子类继承但却在子类中无法直接访问。