C++类和对象练习

这篇具有很好参考价值的文章主要介绍了C++类和对象练习。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.设计一个立方体类 Box,它能计算并输出立方体的体积和表面积

要求:
(1)包含成员变量 m_a(立方体边长)。
(2)包含函数 SetA(doublea)(设置立方体边长)、GetVolume()(计算体积)、GetArea()(计算表面积)。
(3)包含函数 Display(),用来输出计算的结果。
(4)设计测试用主函数 main(),用来测试 Box 类。

#include<iostream>
using namespace std;
class Box
{
public:
	double m_a;
	void SetA(double);
	double GetVolume();
	double GetArea();
	void Display();
};

void Box::SetA(double x)
{
	m_a = x;
}

double Box::GetVolume()
{
	return m_a * m_a * m_a;
}

double Box::GetArea()
{
	return m_a * m_a * 6;
}

void Box::Display()
{
	cout << "体积:" << this->GetVolume() << "面积:" << this->GetArea() << endl;
}
int main()
{
	double a;
	cin >> a;
	Box object1;
	object1.SetA(a);
	object1.Display();
	return 0;
}

2. 创建一个带非缺省构造函数和析构函数的类,这些函数都显示一些信息来表示它们的存在。写一段代码验证构造函数与析构函数何时被调用。

#include<iostream>
using namespace std;
class A {
public:
	int a;
	A(int x) 
	{
		a = x;
		cout << "含参构造" << endl;
	}
	A() 
	{
		a = 0;
		cout << "无参构造" << endl;
	}
	A(const A& x) 
	{ 
		cout << "拷贝构造" << endl;
	}
	~A() 
	{ 
		cout << "析构" << this->a << endl;
	}
};
int main() {
	A a1(100), a2 = a1, a3;
	a2.a = 200, a3.a = 300;
	return 0;
}

C++类和对象练习

3. 写一个有拷贝构造函数的类,在拷贝构造函数里用 cout 打印一些信息。写一个函数,这个函数通过传值方式传入新类的对象。写另一个函数,在这个函数内创建这个新类的局部对象,通过传值方式返回这个对象。在 main 函数中调用这些函数以证明通过传值方式传递和返回对象时,拷贝构造函数确实悄悄地被调用了

#include<iostream>
using namespace std;
class A {
public:
	int a;
	A(int x) {
		a = x;
		cout << "含参构造" << endl;
	}
	A() {
		a = 0;
		cout << "无参构造" << endl;
	}
	A(const A& x) { cout << "拷贝" << endl; }
	~A() { cout << "析构" << endl; }
};
A t1(A x) {
	cout << "t1(函数通过传值方式传入新类的对象)" << endl;
	return x;
}
void t2(A x) {
	A aa;
	aa = t1(x);//对位拷贝不调用拷贝构造函数,这里是关于运算符重载的问题
	cout << "t2(创建这个新类的局部对象,通过传值方式返回这个对象)" << endl;
}
int main() {
	A a1(100), a2, a3 = a1;
	cout << endl;
	t1(a1);
	cout << endl;
	t2(a1);
	cout << endl;
	return 0;
}

C++类和对象练习

4. 编写一个 Person 类

包括:
(1)普通数据成员:姓名(char *类型),性别,年龄。
(2)三个构造函数:无参数构造函数,有参数构造函数(参数:姓名,年龄,性别),拷贝构造函数。
(3)析构函数,输出人员信息函数 print()。
(4)编写 main()函数,分别调用三种构造函数,创建三个对象 P1、P2、P3,其中 P3 的创建是用 P2 通过深拷贝复制得到的。

#include<iostream>
using namespace std;
class Person
{
public:
	char* name;
	char gender;
	int age;
	Person();
	Person(char*, char,int);
	Person(const Person& x);
	~Person();
	void print();
};

Person::Person()
{
	age = -1;
}

Person::Person(char* n, char g, int a)
{
	name = n;
	gender = g;
	age = a;
}

Person::Person(const Person& x)
{
	name = new char[100];
	int len = strlen(x.name);
	for (int i = 0; i < len; i++)
	{
		name[i] = x.name[i];
	}
	name[len] = '\0';
	gender = x.gender;
	age = x.age;
}

Person::~Person()
{
	if (this->age == -1)
		cout << "error" << endl;
	else
		this->print();
}

void Person::print()
{
	cout << this->name << " " << this->gender << " " << this->age << endl;
}
int main() {
	char s1[4] = "Bob";
	char s2[4] = "Baa";
	Person p1(s1, 'm', 9), p2, p3 = p1;
	p3.name = s2;
	return 0;
}

注意:

①深拷贝的写法
const char* s = "asdfg";
③char*s可以直接用字符数组的首地址赋值
④字符数组结尾符’/0’

5.设计一个学生类,保证这个类最多只有一个实例(不可能创建多个类实例),并提供一个访问这个实例的接口函数。

(提示:创建实例通常通过构造函数完成,如何定义构造函数才能保证别人不能随便创建实例?)

#include<iostream>
using namespace std;
class Student
{
public:
	static Student *Create();
	int data;
private:
	Student();
	static Student* p;
};
Student* Student::p = nullptr;
Student* Student::Create()
{
	if (p == nullptr)
	{
		p = new Student();
	}
	return p;
}

Student::Student()
{
	p = nullptr;
	data = 0;
}

int main() {
	Student* p1, * p2;
	p1 = Student::Create();
	p2 = Student::Create();
	cout << p1->data << endl;
	p1->data++;
	cout << p2->data;
	return 0;
}

注意:

Student* Student::p = nullptr;必须要有
②p放在private或public中均可,但是构造函数必须放在private中
③两个Static必须要有

6.设计一个类 Stud

包括:
(1)数据成员:学号、姓名和成绩,以及两个静态变量分别存放总分和人数。
(2)有两个普通成员函数 SetData()和 Disp(),分别用于给数据成员赋值和输出数据成员的值。另有一个静态成员函数 Avg(),它用于计算平均分。
(3)一个友元函数 Compare(),用于比较两个学生成绩高低。
(4)在 main()函数中定义一个对象数组并完成对对象的初始化,并求出最高分和最低分的学生

#include<iostream>
using namespace std;
class Student
{
public:
	static int num, sum_grade;
	int number, grade;
	string name;
	void SetData(int, int, string);
	void Disp();
	void Avg();
	void Compare(Student);
};
int Student::num = 0;
int Student::sum_grade = 0;
int main() {
	Student class1[4];
	string names[4] = { "aa","bb","cc" };
	int numbers[4] = { 1,2,3 };
	int grades[4] = { 82,99,98 };
	for (int i = 0; i < 3; i++)
	{
		class1[i].SetData(numbers[i], grades[i], names[i]);
	}
	class1[0].Avg();
	class1[0].Compare(class1[1]);
	class1[0].Disp();
	return 0;
}

void Student::SetData(int nu, int gr, string nam)
{
	number = nu, grade = gr;
	name = nam;
	num++;
	sum_grade += gr;
}

void Student::Disp()
{
	cout << number << ' ' << name << ' ' << grade << endl;
}

void Student::Avg()
{
	float aws = 0;
	aws = sum_grade / num;
	cout << "平均分:" << aws << endl;
}

void Student::Compare(Student x)
{
	if (grade > x.grade)
	{
		cout << name << "分数较高" << endl;
	}
	else if(grade < x.grade)
	{
		cout << x.name << "分数较高" << endl;
	}
	else
	{
		cout << "两者一样高" << endl;
	}
}

注意:

static必须在外部初始化int Student::num = 0;

7. 写一个包含重载的运算符+、- 、*、/和赋值符的 number 类。出于效率考虑,为这些函数合理地选择返回值以便以链式写表达式。

#include<iostream>
using namespace std;
class A {
public:
	int n;
	A(int r)
	{
		n = r;
	}
	A()
	{
		n = 0;
	}
	A operator+(const A& r) {
		A c;
		c.n = n + r.n;
		return c;
	}
	A operator-(const A& r) {
		A c;
		c.n = n - r.n;
		return c;
	}
	A operator*(const A& r) {
		A c;
		c.n = n * r.n;
		return c;
	}
	A operator/(const A& r) {
		A c;
		c.n = n / r.n;
		return c;
	}
	//++a:前缀++返回++之后的值,因此通常返回类对象本身(返回类型为引用)
	A& operator ++ () {
		n++;
		return *this;
	}
	//a++:需要返回++之前的值,因此函数通常返回对象的一个copy(返回类型非引用)
	A operator ++ (int) {
		A s = *this;
		n++;
		return s;
	}
	//如果返回值不是引用,(a=b)=c中,a=b返回的不是a本身,而是一个临时变量,那么(a=b)=c相当于c的值最后没有赋值给a
	A& operator=(const A& r) {
		n = r.n;
		return *this;
	}
};
int main()
{
	A a1(1), a2(2), a3(3);
	a3++;
	cout << a3.n << ' ';
	++a3;
	cout << a3.n << ' ';
	(a1 = a2) = a3;
	cout << a1.n << endl;	
	return 0;
}

注意:

①++a:前缀++返回++之后的值,因此通常返回类对象本身(返回类型为引用)
②a++:需要返回++之前的值,因此函数通常返回对象的一个copy(返回类型非引用)
③如果返回值不是引用,(a=b)=c中,a=b返回的不是a本身,而是一个临时变量,那么(a=b)=c相当于c的值最后没有赋值给a
④+、-、*、/返回的总是临时变量的值,不能返回this的值,否则运算的本质将会发生改变

8. 设计一个 Rational 类,进行带分数的运算。要求:

(1)包含两个整数成员变量表示分子和分母。
(2)包含一个对所声明对象初始化的构造函数。不提供参数时,构造函数应提供默认值。分数存放成简化形式,例如分数“2/4”应在对象中存放成分子 1 和分母 2 的形式。
(3)对下列情况提供 public 成员函数:
a)两个 Rational 值相加,结果保存成简化形式。
b)两个 Rational 值相减,结果保存成简化形式。
c)两个 Rational 值相乘,结果保存成简化形式。
d)两个 Rational 值相除,结果保存成简化形式。
e)按 a/b 形式打印 Rational 值,其中 a 为分子,b 为分母。
(4)编写主函数,测试 Rational 类。
(5)将上述成员函数改为运算符重载的形式,分别作为成员函数和友元函数实现上述功能
成员函数:

#include<iostream>
using namespace std;
class Rationa
{
private:
	int zi, mu;
public:
	Rationa();
	Rationa(int,int);
	Rationa jianhua();
	friend Rationa operator+(Rationa r, Rationa s);
	Rationa operator-(const Rationa&);
	Rationa operator*(const Rationa&);
	Rationa operator/(const Rationa&);
	void disp();
};

Rationa::Rationa()
{
	zi = 1, mu = 1;
}

Rationa::Rationa(int z, int m)
{
	zi = z, mu = m;
}

Rationa Rationa::jianhua()
{
	int m = min(zi, mu);
	for (int i = m; i > 0; i--)
	{
		if (zi % m == 0 && mu % m == 0)
		{
			zi /= m, mu /= m;
			return *this;
		}
	}
	return *this;
}

Rationa operator+(Rationa r, Rationa s)
{
	Rationa t1 = r, t2 = s;
	t1.zi *= t2.mu, t1.mu *= t2.mu;
	t2.zi *= t1.mu, t2.mu *= t1.mu;
	t1.zi += t2.zi;
	return t1;
}

Rationa Rationa::operator-(const Rationa& r)
{
	Rationa t = r;
	zi *= t.mu, mu *= t.mu;
	t.zi *= mu, t.mu *= mu;
	t.zi = zi - t.zi;
	t = t.jianhua();
	return t;
}

Rationa Rationa::operator*(const Rationa& r)
{
	Rationa t;
	t.zi = zi * r.zi, t.mu = mu * r.mu;
	t = t.jianhua();
	return t;
}

Rationa Rationa::operator/(const Rationa& r)
{
	Rationa t;
	t.zi = zi * r.mu, t.mu = mu * r.zi;
	t = t.jianhua();
	return t;
}

void Rationa::disp()
{
	if ((zi < 0 && mu < 0) || (zi > 0 && mu > 0) || zi == 0 || mu == 0)
	{
		int i;
	}
	else
	{
		cout << '-';
	}

	*this = this->jianhua();

	if (mu == 1)
	{
		cout << abs(zi) << endl;
	}
	else if (zi == 0)
	{
		cout << 0 << endl;
	}
	else if (mu == 0)
	{
		cout << "error" << endl;
	}
	else
	{
		cout << abs(zi) << '/' << abs(mu) << endl;
	}
}

int main()
{
	Rationa r1(2, 4), r2(36, 9), r3(0, 1), r4(1, 0);
	r1.disp(), r2.disp(), r3.disp(), r4.disp();
	(r1 * r2).disp();
	(r1 / r2).disp();
	(r1 - r2).disp();
	(r1 + r2).disp();
	return 0;
}

9. 定义一个二维方阵类 matrix。通过重载二元运算符“+”、“-”、“*”和一元运算符“~”, 来实现矩阵加、矩阵减、矩阵乘以及矩阵转置。

#include<iostream>
using namespace std;
class matrix {
public:
	int r, c; //r行c列
	int** mem; //矩阵数据
	matrix(int a, int b);//a行b列
	matrix();
	~matrix();
	matrix(const matrix&);
	matrix operator+ (const matrix& m);
	matrix operator- (const matrix& m); 
	matrix operator* (const matrix& m); 
	matrix& operator= (const matrix& m);
	matrix operator~ (); //矩阵转置
	void display(); 
};

matrix::matrix(int a, int b)
{
	r = a, c = b;
	mem = new int* [r];
	for (int i = 0; i < r; i++)
	{
		mem[i] = new int[c];
	}
	//输入矩阵
	for (int i = 0; i < r; i++)
		for (int j = 0; j < c; j++)
			mem[i][j] = i + 1;
}

matrix::matrix()
{
	r = 1, c = 1;
	mem = new int* [r];
	for (int i = 0; i < r; i++)
	{
		mem[i] = new int[c];
	}
	for (int i = 0; i < r; i++)
		for (int j = 0; j < c; j++)
			mem[i][j] = 0;
}

matrix::~matrix()
{
	for (int i = 0; i < r; i++) {
		delete[] mem[i];
	}
	delete[] mem;
}

matrix::matrix(const matrix&t)
{
	r = t.r, c = t.c;
	mem = new int* [r];
	for (int i = 0; i < r; i++)
	{
		mem[i] = new int[c];
	}
	for (int i = 0; i < r; i++)
		for (int j = 0; j < c; j++)
			mem[i][j] = t.mem[i][j];
}

matrix matrix::operator+(const matrix& m)
{
	matrix t(r, c);
	if (r == m.r && c == m.c)
	{	
		for (int i = 0; i < r; i++)
			for (int j = 0; j < c; j++)
				t.mem[i][j] = mem[i][j] + m.mem[i][j];
		return t;
	}
	else
	{
		cout << "error" << endl;
		t.mem = nullptr;
		return t;
	}
}

matrix matrix::operator-(const matrix& m)
{
	matrix t(r, c);
	if (r == m.r && c == m.c)
	{
		for (int i = 0; i < r; i++)
			for (int j = 0; j < c; j++)
				t.mem[i][j] = mem[i][j] - m.mem[i][j];
		return t;
	}
	else
	{
		cout << "error" << endl;
		t.mem = nullptr;
		return t;
	}
}

matrix matrix::operator*(const matrix& m)
{
	matrix t(r, m.c);
	if (c == m.r)
	{
		for (int i = 0; i < t.r; i++)
			for (int j = 0; j < t.c; j++)
				t.mem[i][j] = 0;
		for (int i1 = 0; i1 < r; i1++)
			for (int j1 = 0; j1 < m.c; j1++)
				for (int k1 = 0; k1 < c; k1++)
					t.mem[i1][j1] += (mem[i1][k1] * m.mem[k1][j1]);
		return t;
	}
	else
	{
		cout << "error" << endl;
		t.mem = nullptr;
		return t;
	}
}

matrix & matrix::operator=(const matrix& t)
{
	r = t.r, c = t.c;
	mem = new int* [r];
	for (int i = 0; i < r; i++)
	{
		mem[i] = new int[c];
	}
	for (int i = 0; i < r; i++)
		for (int j = 0; j < c; j++)
			mem[i][j] = t.mem[i][j];
	return *this;
}

matrix matrix::operator~()
{
	matrix t(c, r);
	for (int i = 0; i < r; i++)
		for (int j = 0; j < c; j++)
			t.mem[j][i] = mem[i][j];
	return t;
}

void matrix::display()
{
	for (int i = 0; i < r; i++) {
		for (int j = 0; j < c; j++) {
			cout << mem[i][j] << ' ';
		}
		cout << endl;
	}
	cout << "==========================" << endl;
}
int main()
{
	matrix a1(3, 2), a2(2, 2), a3(2, 2), a4;
	a1.display();
	a2.display();
	(a1 * a2).display();
	(a2 + a3).display();
	(~a1).display();
	a4 = a3 + a2;
	a4.display();
	return 0;
}

注意

①涉及动态分配内存,一定要留意拷贝构造函数、=重载
②二维数组动态分配内存方法
③矩阵乘法代码实现
④重载等号的返回值必须是引用才可实现连等
⑤析构函数释放内存的方法文章来源地址https://www.toymoban.com/news/detail-417053.html

到了这里,关于C++类和对象练习的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【css】动画:立方体相册

    2024年02月11日
    浏览(49)
  • Opengl之立方体贴图

    简单来说, 立方体贴图就是一个包含了6个2D纹理的纹理 ,每个2D纹理都组成了 立方体的一个面 :一个有纹理的立方体。你可能会奇怪,这样一个立方体有什么用途呢?为什么要把6张纹理合并到一张纹理中,而不是直接使用6个单独的纹理呢?立方体贴图有一个非常有用的特

    2024年02月07日
    浏览(41)
  • OpenGLES:3D立方体纹理贴图

    前几篇博文讲解了OpenGLES绘制多种3D图形,并赋予丰富的色彩,但是在这些3D图形绘制过程中,有一点还没有涉及,就是 纹理贴图。 今天这篇博文我会用如下 六张图片 对立方体进行纹理贴图,实现 六个面都是贴图 的3D旋转立方体 2.1 常规变量定义 2.2 顶点、纹理相关变量定义

    2024年02月08日
    浏览(42)
  • 【Filament】立方体贴图(6张图)

    ​ 本文通过一个立方体贴图的例子,讲解三维纹理贴图(子网格贴图)的应用,案例中使用 6 张不同的图片给立方体贴图,图片如下。 ​ 读者如果对 Filament 不太熟悉,请回顾以下内容。 Filament环境搭建 绘制三角形 绘制矩形 绘制圆形 绘制立方体 纹理贴图 ​ 本文项目结构

    2024年03月09日
    浏览(51)
  • VCG 网格简化之移动立方体

    我们先来回顾一下原始的移动立方体算法,该算法的基本思想是通过找出所有与等值面相交的体素,在这些基础上再分别找出每个体素与等值面相交的交面,最终将这些交面连在一起即是我们所求的曲面。其大致过程如下所述: (1)首先将点云在空间上进行体素划分,并对

    2024年01月22日
    浏览(45)
  • 【libGDX】Mesh立方体贴图(6张图)

    ​ 本文通过一个立方体贴图的例子,讲解三维纹理贴图的应用,案例中使用 6 张不同的图片给立方体贴图,图片如下。 ​ 读者如果对 libGDX 不太熟悉,请回顾以下内容。 使用Mesh绘制三角形 使用Mesh绘制矩形 使用Mesh绘制圆形 使用Mesh绘制立方体 Mesh纹理贴图 ​ 本节将使用

    2024年03月09日
    浏览(61)
  • GLES学习笔记---立方体贴图(一张图)

    立方体贴图 如上图是一张2D纹理,我们需要将这个2D纹理贴到立方体上,立方体有6个面,所以上面的2D图分成了6个面,共有14个纹理坐标 上边的立方体一共8个顶点坐标,范围是[-1, 1]; 我们要做的是将纹理图贴到这6个面上面 我们绘制的时候使用了VBO、VAO、EBO、 indices里面是绘

    2024年01月19日
    浏览(53)
  • 项目管理之干系人立方体分析

    权力利益方格、权力影响方格,或作用影响方格 :基于干系人的职权级别(权力)、对项目成果的关心程度(利益)、对项目成果的影响能力(影响),或改变项目计划或执行的能力,每一种方格都可用于对干系人进行分类。对于小型项目、干系人与项目的关系很简单的项目,或干系

    2024年02月06日
    浏览(47)
  • 计算机图形学 | 实验六:旋转立方体

    华中科技大学《计算机图形学》课程 MOOC地址:计算机图形学(HUST) 在正式搭建环境之前,我们先来介绍一下读完下面的部分你会了解些什么。 绘制出旋转立方体需要的新知识 认识一些 OpenGL的新功能 接下来,我们来介绍一下绘制旋转立方体。绘制效果如下: Z-缓存(Z-Buff

    2024年02月06日
    浏览(52)
  • Opengl学习-立方体贴图踩坑记录

    2023/10/25 星期三 昨晚写到了凌晨1点,今早终于查出了问题,写一篇随笔记录一下 绑定到特定纹理单元,沿用 TEXTURE_2D 方式: (更正)Cubemap可以使用Mipmap,但 GL_TEXTURE_MAG_FILTER 不可设置为带MIPMAP类型,否则将引发 GL_INVALID_ENUM = 1280 错误 可以主动加载多个Mipmap level,在 glTexIm

    2024年02月08日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包