C++继承与派生--访问控制

继承与派生

说明:以下实验证明一个是出自以Person类为父类,Student为子类的源代码,另一个出自以Point为父类,Recetangle为子类的源代码

派生类生成过程

1.吸收基类成员

2.改造基类成员

3.添加新成员

过程三步骤详述

  • 吸收基类成员

    派生过程中构造函数和析构函数都不被继承,因此在对派生类新增成员进行初始化,需要在派生类写构造函数负责对新增成员的初始化,而从基类继承的成员,依旧由基类的构造函数完成

  • 改造基类成员

    (1)基类成员的访问问题,靠继承方式控制

    (2)对基类数据或函数成员的覆盖和隐藏,如果派生类声明了一个和某个基类成员同名的新成员(注:函数要参数相同,如果不同的话,就是函数重载),派生的新成员会隐藏基类中同名的函数,并且在类外通过生成对象来直接使用成员名时,基类的成员就会被隐藏,即同名隐藏

同名隐藏

同名隐藏前:

同名隐藏后:

  • 添加新成员

    通过派生类中新成员派生类新功能的实现:

Person类中的成员函数:

Student类中的成员函数:

访问控制

  • 继承语法:

    Class 派生类名:继承方式(public private protected) 基类名{}
  • 分类:

    (1)公有继承:(常用)

    当类的继承方式是公有继承,即public时,父类中public和protected中的成员访问属性不变,而父类private中的成员在子类中不能直接访问,可通过从父类中继承的公共接口对此进行操作

私有成员报错

公有和保护成员不报错

(2)私有继承:(不常用)

当类的继承方式是私有继承,即private时,父类的公有成员和保护成员以私有成员的身份出现在子类中,在子类内部可以互相互访问,但在类外通过对象就不能访问和操作,而父类private中的成员在子类中还是子类外都不能直接访问经过私有继承后,父类中的成员成为子类私有成员或者不可直接访问的成员,那么如果进一步派生的话,基类的全部成员就无法在新的派生类中直接访问

子类内部不报错

通过对象访问报错

(3)保护继承:

当类的继承方式是保护继承,即protected时,父类的公有成员和保护成员以保护成员的身份出现在子类中,在子类内部可以互相访问,但在类外通过对象就不能访问和操作,而父类private中的成员在子类中还是子类外都不能直接访问

子类内部不报错

通过对象访问报错

以上所有实验的代码

以Point类为父类,Recetangle为子类的源代码

头文件声明:

#ifndef POINT_H
#define POINT_H

//Point类定义

class Point
{
public:
	void initP(float xx , float yy ) ;
	void move(float xoff, float yoff);
	float getX() const;
	float getY() const;
private:
	float x, y;
};

//retangle类定义
class Recetangle:private Point
{
public:
    void initR(float x, float y, float w, float h);
	float getWidth() const;
	float getHeight() const;
private:
	float w, h;
};

头文件函数实现:

#include "point.h"
#include<iostream>

using namespace std;

//point类函数实现
 void Point::initP(float xx=0, float yy = 0) 
{
	x=xx;
	y=yy;
}
void Point::move(float xoff, float yoff)
{
	x += xoff;
	y += yoff;
}
float Point::getX() const
{
	return x;
}
float Point::getY() const
{
	return y;
}


//Recetangle类函数实现
 void Recetangle::initR(float x, float y, float w, float h)
{
	initP(x, y);//私有继承,公有成员子类内部可以访问
	this->w = w;
	this->h = h;
}
float Recetangle::getHeight() const
{
	return h;
}
float Recetangle::getWidth() const
{
	return w;
}

main函数:

#include"point.h"
#include <iostream>

using namespace std;

int main()
{
	/*Recetangle test;
	test.initR(2, 3, 20, 30);
	test.move(3, 2);
	cout << test.getX() << "  "
		<< test.getY ()<< "  "
		<< test.getWidth() << "  "
		<<test.getHeight() << "  "
		<< endl;*/

	//Recetangle test2;
	//test2.getX();//以私有继承,在类外通过对象进行访问,编译器报错
	//test2.getY();

	//Recetangle test3;
	//test3.getX();
	//test3.initP();//以保护继承,在类外不能通过对象访问
			
	return 0;
}

以Person类为父类,Student为子类的源代码

头文件声明:

#ifndef PCH_H
#define PCH_H

#include<string>

using namespace std;

class Person
{
public:
	Person();
	~Person();
	void Inputinfo();
	void Showinfo() const;
private:
	string name;
protected:
	int age;
	
};
class Student:public Person
{
public:
	Student();
	void Inputinfo2();
	//void Inputinfo();//同名隐藏实验
	void Showinfo2() const;

private:
	float  grades;
	int id;
};

头文件中函数实现:

#include "pch.h"
#include<iostream>
#include<string>

using namespace std;


/****Person类成员函数实现****/

//功能:构造函数
Person::Person():name(name),age(age){}

//功能:析构函数,人数减1
Person::~Person(){}

//功能:输入用户名字、年龄
void Person::Inputinfo()
{
	cout << "Pleasing input your name" << endl;
	cin >> name;
	cout << "Pleasing input your age" << endl;
	cin >> age;
}

//功能:显示用户名字、年龄
void Person::Showinfo() const
{
	cout << "用户名: " << name << " \t " << "年龄 :" << age;
	
}



/****Student类成员函数的实现****/

//功能:Student类中构造函数实现
Student::Student():id(id),grades(grades){}

//功能:输入学生名字、年龄、学号、成绩
void Student::Inputinfo2()
{
	Inputinfo();
	cout << "Pleasing input your id" << endl;
	cin >> id;
	cout << "Pleasing input your grades" << endl;
	cin >> grades;
}

////功能:输入学生学号、成绩(实现同名隐藏,通过对象操作时同名函数采取就近原则)
//void Student::Inputinfo()
//{
//	cout << "Pleasing input your id" << endl;
//	cin >> id;
//	cout << "Pleasing input your grades" << endl;
//	cin >> grades;
//}

//功能:显示学生名字、年龄、学号、成绩
void Student::Showinfo2() const
{
	Showinfo();
	cout << "\t";
	cout << "学号: " << id << " \t " << "成绩: " << grades << endl;
}

////测试子类不能直接访问父类私有成员,编译器报错
//void Student::Showinfo2() const
//{
//	cout << name
//		<< age;
//}


////测试以public继承,父类的公有成员和保护成员在子类内部可以直接访问,编译器不报错
//void Student::Showinfo2() const
//{
//	Showinfo();//父类公有成员
//	cout << age;//在做这步实验时,将原本私有成员的age改成了保护成员
//	cout << "\t";
//	cout << "学号: " << id << " \t " << "成绩: " << grades << endl;
//}

main函数:

#include "pch.h"
#include <iostream>
#include<string>

using namespace std;


int main()
{
	/*Person p1;
	p1.Inputinfo();
	p1.Showinfo();*/

	Student stu1;
	//stu1.Inputinfo();//同名隐藏前,原本Person类中Inputinfo函数输入的是name和age
	stu1.Inputinfo2();
	stu1.Showinfo2();

	return 0;
}
posted @ 2019-10-12 17:40  依言  Views(576)  Comments(0Edit  收藏  举报