类的继承派生析构函数虚基类

Posted Roam-G

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了类的继承派生析构函数虚基类相关的知识,希望对你有一定的参考价值。

7-1

//Point.h
#ifndef _POINT_H
#define _POINT_H

class Point {	//基类Point类的定义
public:	//公有函数成员
	void initPoint(float x = 0, float y = 0) {
		this->x = x; this->y = y;
	}
	void move(float offX, float offY) {
		x += offX; y += offY; 
	}
	float getX() const { 
		return x; 
	}
	float getY() const { 
		return y;
	}
private:	//私有数据成员
	float x, y;
};

#endif //_POINT_H
//Rectangle.h
#ifndef _RECTANGLE_H
#define _RECTANGLE_H
#include "Point.h"

class Rectangle: public Point {	//派生类定义部分
public:	//新增公有函数成员
	void initRectangle(float x, float y, float w, float h) {
		initPoint(x, y); //调用基类公有成员函数
		this->w = w;
		this->h = h;
	}
	float getH() const { return h; }
	float getW() const { return w; }
private:	//新增私有数据成员
	float w, h;
};

#endif //_RECTANGLE_H
//7_1.cpp
#include <iostream>
#include <cmath>
#include "Rectangle.h"
using namespace std;

int main() {
	Rectangle rect;	//定义Rectangle类的对象
	rect.initRectangle(2, 3, 20, 10);	//设置矩形的数据
	rect.move(3,2);	//移动矩形位置
	cout << "The data of rect(x,y,w,h): " << endl;
	cout << rect.getX() <<", "	//输出矩形的特征参数
		<< rect.getY() << ", "
		<< rect.getW() << ", "
		<< rect.getH() << endl;
	return 0;
}
//7_3.cpp
#include <iostream>
using namespace std;

class Base1 { //基类Base1定义
public:
	void display() const { 
		cout << "Base1::display()" << endl; 
		}
};

class Base2: public Base1 { //公有派生类Base2声明定义
public:
	void display() const { 
		cout << "Base2::display()" << endl; 
		}
};

class Derived: public Base2 { //公有派生类Derived声明定义
public:
	void display() const {
		cout << "Derived::display()" << endl; 
		}
};

void fun(Base1 *ptr) { //参数为指向基类对象的指针
	ptr->display();	//"对象指针->成员名"
}

int main() {	//主函数
	Base1 base1;	//声明Base1类对象
	Base2 base2;	//声明Base2类对象
	Derived derived;	//声明Derived类对象

	fun(&base1);	//用Base1对象的指针调用fun函数
	fun(&base2);	//用Base2对象的指针调用fun函数
	fun(&derived);	//用Derived对象的指针调用fun函数

	return 0;
}
//7_4.cpp
#include <iostream>
using namespace std;

class Base1 {	//基类Base1,构造函数有参数
public:
	Base1(int i) { 
		cout << "Constructing Base1 " << i << endl; }
};

class Base2 {	//基类Base2,构造函数有参数
public:
	Base2(int j) { cout << "Constructing Base2 " << j << endl; }
};

class Base3 {	//基类Base3,构造函数无参数
public:
	Base3() { cout << "Constructing Base3 *" << endl; }
};

class Derived: public Base2, public Base1, public Base3 {
//派生新类Derived,注意基类名的顺序
public:	//派生类的公有成员
	Derived(int a, int b, int c, int d): Base1(a), member2(d), member1(c), Base2(b) { }
	//注意基类名的个数与顺序,注意成员对象名的个数与顺序
private:	//派生类的私有成员对象
	Base1 member1;
	Base2 member2;
	Base3 member3;
};

int main() {
	Derived obj(1, 2, 3, 4);
	return 0;
}
//7_5.cpp
#include <iostream>
using namespace std;

class Base1 {	//基类Base1,构造函数有参数
public:
	Base1(int i) { cout << "Constructing Base1 " << i << endl; }
	~Base1() { cout << "Destructing Base1" << endl; }
};

class Base2 {	//基类Base2,构造函数有参数
public:
	Base2(int j) { cout << "Constructing Base2 " << j << endl; }
	~Base2() { cout << "Destructing Base2" << endl; }
};

class Base3 {	//基类Base3,构造函数无参数
public:
	Base3() { cout << "Constructing Base3 *" << endl; }
	~Base3() { cout << "Destructing Base3" << endl; }
};

class Derived: public Base2, public Base1, public Base3 {
//派生新类Derived,注意基类名的顺序
public:	//派生类的公有成员
	Derived(int a, int b, int c, int d): Base1(a), member2(d), member1(c), Base2(b) { }
	//注意基类名的个数与顺序,注意成员对象名的个数与顺序
private:	//派生类的私有成员对象
	Base1 member1;
	Base2 member2;
	Base3 member3;
};

int main() {
	Derived obj(1, 2, 3, 4);
	return 0;
}
//7_6.cpp
#include <iostream>
using namespace std;

class Base1 {	//定义基类Base1
public:
	int var;
	void fun() { cout << "Member of Base1" << endl; }
};

class Base2 {	//定义基类Base2
public:
	int var;
	void fun() { cout << "Member of Base2" << endl; }
};

class Derived: public Base1, public Base2 {	//定义派生类Derived
public:
	int var;	//同名数据成员
	void fun() { cout << "Member of Derived" << endl; }	//同名函数成员
};

int main() {
	Derived d;
	Derived *p = &d;

	d.var = 1;	//对象名.成员名标识
	d.fun();	//访问D1类成员
	
	d.Base1::var = 2;	//作用域分辨符标识
	d.Base1::fun();	//访问Base1基类成员
	
	p->Base2::var = 3;	//作用域分辨符标识
	p->Base2::fun();	//访问Base2基类成员

	return 0;
}
//7_7.cpp
#include <iostream>
using namespace std;

class Base0 {	//定义基类Base0
public:
	int var0;
	void fun0() { cout << "Member of Base0" << endl; }
};

class Base1: public Base0 {	//定义派生类Base1
public:	//新增外部接口
	int var1;
};

class Base2: public Base0 {	//定义派生类Base2
public:	//新增外部接口
	int var2;
};

class Derived: public Base1, public Base2 {	//定义派生类Derived
public:	//新增外部接口
	int var;
	void fun() { cout << "Member of Derived" << endl; }
};

int main() {	//程序主函数
	Derived d;			//定义Derived类对象d
	d.Base1::var0 = 2;	//使用直接基类
	d.Base1::fun0();
	d.Base2::var0 = 3;	//使用直接基类
	d.Base2::fun0();
	return 0;
}
//7_8.cpp
#include <iostream>
using namespace std;

class Base0 {	//定义基类Base0
public:
	int var0;
	void fun0() { cout << "Member of Base0" << endl; }
};

class Base1: virtual public Base0 {	//定义派生类Base1
public:	//新增外部接口
	int var1;
};

class Base2: virtual public Base0 {	//定义派生类Base2
public:	//新增外部接口
	int var2;
};

class Derived: public Base1, public Base2 {	//定义派生类Derived
public:	//新增外部接口
	int var;
	void fun() { cout << "Member of Derived" << endl; }
};

int main() {	//程序主函数
	Derived d;	//定义Derived类对象d
	d.var0 = 2;	//直接访问虚基类的数据成员
	d.fun0();	//直接访问虚基类的函数成员
	return 0;
}
//7_9.cpp  文件五,主函数
#include "LinearEqu.h"	//类定义头文件
#include <iostream>
using namespace std;

int main() {	//主函数
	double a[]=	{ //方程系数矩阵
		0.2368, 0.2471, 0.2568, 1.2671,		//第一行
		0.1968, 0.2071, 1.2168, 0.2271,		//第二行
		0.1581, 1.1675, 0.1768, 0.1871,		//第三行
		1.1161, 0.1254, 0.1397, 0.1490 };	//第四行
	double b[] = { 1.8471, 1.7471, 1.6471, 1.5471 };//方程右端项
	LinearEqu equ(4);	//定义一个四元方程组对象
	equ.setLinearEqu(a,b);	//设置方程组
	equ.printLinearEqu();	//输出方程组
	if (equ.solve())	//求解方程组
		equ.printSolution();	//输出方程组的解
	else
		cout<<"Fail"<<endl;
	return 0;
}
//LinearEqu.cpp  文件四,LinearEqu类实现
#include "LinearEqu.h"	//包含类的定义头文件
#include <iostream>
#include <cmath>
using namespace std;

LinearEqu::LinearEqu(int size/* = 2 */) : Matrix(size) {	//用size调用基类构造函数
	sums = new double[size];	//动态内存分配
	solution = new double[size];
}

LinearEqu::~LinearEqu()	{ //派生类LinearEqu的析构函数
	delete[] sums;	//释放内存
	delete[] solution;
	//会自动调用基类析构函数
}

void LinearEqu::setLinearEqu(const double *a, const double *b) {	//设置线性方程组
	setMatrix(a);	//调用基类函数
	for(int i = 0; i < getSize(); i++)
		sums[i] = b[i];
}

void LinearEqu::printLinearEqu() const {	//显示线性方程组
	cout << "The Line eqution is:" << endl;
	for (int i = 0; i < getSize(); i++) {
		for (int j = 0; j < getSize(); j++)
			cout << element(i, j) << " ";
			cout << "     " << sums[i] << endl;
		}
}

void LinearEqu::printSolution() const {	//输出方程的解
	cout << "The Result is: " << endl;
	for (int i = 0; i < getSize(); i++)
		cout << "x[" << i << "] = " << solution[i] << endl;
}

inline void swap(double &v1, double &v2) {	//交换两个实数
	double temp = v1;
	v1 = v2;
	v2 = temp;
}

bool LinearEqu::solve() {	//全选主元素高斯消去法求解方程
	int *js=new int[getSize()];	//存储主元素所在列号的数组
	for (int k = 0; k < getSize() - 1; k++)	{ 
		//选主元素
		int is;	//主元素所在行号
		double max = 0;	//所有元素的最大值
		for (int i = k; i < getSize(); i++)
			for (int j = k; j < getSize(); j++) {
				double t = fabs(element(i, j));
				if (t > max) {
					max = t;
					js[k] = j;
					is = i;
				}
			}
		if (max == 0) {
			delete[] js;
			return false;
		} else {
			//通过行、列交换,把主元素交换到第k行第k列
			if (js[k] != k)
				for (int i = 0; i < getSize(); i++)
					swap(element(i, k), element(i, js[k]));
			if (is != k) {
				for (int j = k; j < getSize(); j++)
					swap(element(k, j), element(is, j));
				swap(sums[k], sums[is]);
			}
		}
		//消去过程
		double major = element(k, k);
		for (int j = k + 1; j < getSize(); j++)
			element(k, j) /= major;
		sums[k] /= major;
		for (int i = k + 1; i < getSize(); i++) {
			for (int j = k + 1; j < getSize(); j++)
				element(i, j) -= element(i, k) * element(k, j);
			sums[i] -= element(i, k) * sums[k];
		}
	}
	//判断剩下的一个元素是否等于0
	double d = element(getSize() - 1, getSize() - 1);
	if (fabs(d) < 1e-15) {
		delete[] js;
		return false;
	}
	//回代过程
	solution[getSize() - 1] = sums[getSize() - 1] / d;	
	for (int i = getSize() - 2; i >= 0; i--) {
		double t = 0.0;
		for (int j = i + 1; j <= getSize() - 1; j++)
			t += element(i, j) * solution[j];
		solution[i] = sums[i] - t;
	}
	js[getSize() - 1] = getSize() - 1;
	for (int k = getSize() - 1; k >= 0; k--)
		if (js[k] != k) swap(solution[k], solution[js[k]]);
	delete[] js;
	return true;
}
//LinearEqu.h  文件二,LinearEqu类定义
#ifndef _LINEAR_EQU_H
#define _LINEAR_EQU_H

#include "Matrix.h"

class LinearEqu: public Matrix {	//公有派生类LinearEqu定义
public:	//外部接口
	LinearEqu(int size = 2);	//构造函数
	~LinearEqu();	//析构函数
	void setLinearEqu(const double *a, const double *b);	//方程赋值
	bool solve();	//全选主元高斯消去法求解方程
	void printLinearEqu() const;	//显示方程
	void printSolution() const;	//显示方程的解
private:	//私有数据
	double *sums;	//方程右端项
	double *solution;	//方程的解
};

#endif //_LINEAREQU_H
//Matrix.cpp  文件三,Matrix类实现
#include "Matrix.h"	//包含类的定义头文件
#include <iostream>
using namespace std;

void Matrix::setMatrix(const double *values) {	//设置矩阵
	for (int i = 0; i < size * size; i++)
		elements[i] = values[i];	//矩阵成员赋初值
}

Matrix::Matrix(int size/* = 2 */) : size(size) {	//矩阵Matrix类的构造函数
	elements = new double[size * size];	//动态内存分配
}

Matrix::~Matrix() {	//矩阵Matrix类的析构函数
	delete[] elements;	//内存释放
}

void Matrix::printMatrix() const { //显示矩阵的元素
	cout << "The Matrix is:" << endl;
	for(int i = 0; i < size; i++) {
		for(int j = 0; j < size; j++)
			cout << element(i, j) << " ";
		cout << endl;
	}
}
//Matrix.h  文件一,Matrix类定义
#ifndef _MATRIX_H
#define _MATRIX_H

class Matrix {	//基类Matrix定义
public:	//外部接口
	Matrix(int size = 2);	//构造函数
	~Matrix();	//析构函数
	void setMatrix(const double *values);	//矩阵赋初值
	void printMatrix() const;		//显示矩阵
	int getSize() const { return size; }	//得到矩阵大小
	double &element(int i, int j) { return elements[i * size + j]; }
	double element(int i, int j) const { return elements[i * size + j]; }
private:	//保护数据成员
	int size;	//矩阵的大小
	double *elements;	//矩阵存放数组首地址
};

#endif //_MATRIX_H

以上是关于类的继承派生析构函数虚基类的主要内容,如果未能解决你的问题,请参考以下文章

关于类继承的构造与析构调用分析

实验4 类的继承派生和多态

C++编程经验:为虚基类做虚析构函数的必要性

C++编程经验:为虚基类做虚析构函数的必要性

本周学习小结

[实验6]类的继承与多态