一、公有繼承
當繼承方式爲公有繼承的時候,基類中不同的訪問限定符下的數據成員和成員函數被繼承到了派生類的不同的訪問限定符下。
二、代碼演示
用代碼來驗證上述的理論知識
創建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訪問限定符下,雖然被子類繼承但卻在子類中無法直接訪問。