【C++】程序设计期末复习day02(连更)试卷解析+类和对象

此块会再加上文件流的知识 

基础知识补充:向量

一、向量

1.基础知识

在C++中,std::vector 是一种序列容器,属于标准模板库(STL)的一部分。它提供动态大小的数组功能,可以存储任何类型的元素,并允许在末尾高效地添加或删除元素。

特点:
  • 可以自动调整大小以容纳更多元素。
  • 支持随机访问,即可以直接通过索引访问元素。
基本操作:
  • push_back(): 在向量末尾添加一个元素。
  • pop_back(): 删除向量末尾的元素。
  • size(): 返回向量中的元素数量。
  • at(): 安全访问特定索引的元素,带边界检查。
  • operator[]: 通过索引访问元素,不带边界检查。
  • clear(): 移除向量中的所有元素。
  • reserve(): 预留足够的空间以容纳指定数量的元素。
    //省略前面代码
    vector<int> min1;//创造一个int类型的向量
    int* px = min1.data(); // 获取指向vector数据的指针
    int* py = px + min1.size(); // 获取指向vector末尾的指针
 
   for(int*p=px; p!=py;++p) {
        cout << *p << " "; // 通过解引用指针来输出当前元素
         // 递增指针
    }
    cout << endl;

2.结构体和矢量结合使用

#include <iostream>
#include <vector>
#include <string> // 包含字符串类型的头文件

// 定义一个简单的结构体 Person
struct Person {
    std::string name; // 人的名字
    int age;          // 人的年龄

    // 常规构造函数,分别设置成员变量的初始值
    Person(std::string name, int age) {
        this->name = name;
        this->age = age;
    }
};

int main() {
    // 创建一个存储 Person 实例的向量
    std::vector<Person> people;

    // 使用构造函数创建 Person 实例并添加到向量中
    people.push_back(Person("Alice", 30));
    people.push_back(Person("Bob", 24));
    people.push_back(Person("Charlie", 35));

    // 遍历向量并打印每个 Person 的信息
    for (const Person& person : people) {
        std::cout << "Name: " << person.name << ", Age: " << person.age << std::endl;
    }

    return 0;
}

二、类和对象

类是创建对象的基础,它包含了数据成员(成员变量)和成员函数(方法),但不包含具体的数据。对象就是根据类创建的一个实例。

class Car {
public:
    std::string color; // 成员变量
    void start() { // 成员函数
        std::cout << "The car is starting." << std::endl;
    }
};

int main() {
    Car myCar; // 实例化 Car 类,创建了一个 Car 类型的对象 myCar
    myCar.color = "Red"; // 设置 myCar 的成员变量 color
    myCar.start(); // 调用 myCar 的成员函数 start
    return 0;
}

1.基础结构

  • 定义一个类:就需要定义它的属性和它的行为,我们常常称之为成员变量和成员函数。
  • 一定不要忘记写分号
  • 公有部分and私有部分(不可外部访问,即不可被修改)
class A {
// 访问修饰控制符
public:
    // 成员变量
	int x;
	int y;
    // 成员函数
	int add() {
        return x + y;
    }
private:
    int z;
}

2.struct和class

类 = 结构体 + 成员函数,事实上 C++ 也支持再结构体中定义少量的方法

我们通常根据使用的场景来选择使用结构体还是使用类

  • 结构体:主要用来记录数据,行为极少
  • 类:既有属性也有行为

在C++中 struct和class唯一的区别就在于 默认的访问权限不同

区别:

  • struct 默认权限为公共
  • class 默认权限为私有

3.构造函数和成员函数

构造函数是特殊的成员函数,他无需调用程序会自动执行

  1. 构造函数的特点

    • 构造函数的名称必须与类名完全相同,包括大小写
    • 构造函数没有返回类型,甚至没有 void
    • 构造函数的主要目的是在创建对象时初始化对象。
    • 一个类可以有多个构造函数,这是通过构造函数重载实现的(即具有不同的参数列表)。
  2. 成员函数的特点

    • 成员函数的名称不必与类名相同。
    • 成员函数可以有返回类型,可以是任意有效的C++类型,包括 void
    • 成员函数定义了对象的行为,可以访问和修改对象的状态。
    • 除了构造函数和析构函数,类的其他成员函数都是普通成员函数。
class MyClass {
public:
    // 构造函数的声明
    MyClass();
    MyClass(int value);

    // 成员函数的声明
    void doSomething();
};

// 正确的构造函数的定义,使用作用域解析运算符 ::
MyClass::MyClass() {
    // 默认构造函数的实现
}

MyClass::MyClass(int value) {
    // 带参数的构造函数的实现
}

// 成员函数的定义
void MyClass::doSomething() {
    // doSomething 函数的实现
}

4.构造函数和析构函数

构造函数和析构函数是两种特殊的成员函数。

  • 构造函数:主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用。对象实例化的时候,再分配的空间上构造对象如初始化成员变量,分配资源等等
  • 在C++中,析构函数是一个与对象的生命周期相关联的特殊成员函数。当一个对象的生命周期结束时,析构函数会被自动调用,以执行清理工作。通俗来讲,析构函数就像是一个“打扫房间”的过程,当一个“派对”(对象的生命周期)结束时,析构函数确保所有的“垃圾”(资源)被清理掉,房间恢复到使用前的状态。
class MyClass {
public:
    MyClass() {
        std::cout << "MyClass constructor called." << std::endl;
    }
    ~MyClass() {
        std::cout << "MyClass destructor called." << std::endl;
    }
};

int main() {
    {
        MyClass localObject; // 调用构造函数
        // ...
    } // localObject 作用域结束,调用析构函数

    MyClass* pointer = new MyClass; // 动态分配对象并调用构造函数
    // ...
    delete pointer; // 删除对象,先调用析构函数,然后释放内存

    return 0;
}

在这个示例中,MyClass 有一个构造函数和一个析构函数。当创建 MyClass 对象时,无论是局部对象还是动态分配的对象,构造函数都会被调用。当对象的生命周期结束时,析构函数会被自动调用。对于局部对象 localObject,当它的作用域结束时,析构函数被调用。对于动态分配的对象,当使用 delete 时,先调用析构函数,然后释放内存。

5.静态成员

静态成员是类的一个特性,它属于类本身,而不是类的任何特定实例(对象)。这意味着静态成员在所有对象中是共享的,每个类只有一个这样的成员。以下是静态成员的一些关键特点:

  1. 共享性:静态成员变量被类的所有实例共享。修改静态成员会影响到所有访问该成员的实例。

  2. 类作用域:静态成员的定义和声明在类的作用域内,但它们不属于任何特定的对象实例。

  3. 访问:可以通过类名直接访问静态成员,也可以通过对象实例访问。

  4. 构造函数和析构函数:静态成员没有构造函数或析构函数,它们在程序启动时初始化,并在程序结束时销毁。

静态成员就是在成员变量和成员函数前加上关键字static

class MyClass {
public:
    // 静态成员变量
    static int staticVar;

    // 静态成员函数
    static void staticFunction() {
        // 可以访问静态成员变量
        std::cout << "staticVar: " << staticVar << std::endl;
    }
};

// 静态成员变量的初始化
int MyClass::staticVar = 0;

int main() {
    // 直接通过类名访问静态成员变量和函数
    MyClass::staticVar = 10;
    MyClass::staticFunction(); // 输出 "staticVar: 10"

    // 也可以通过对象实例访问静态成员
    MyClass obj;
    obj.staticVar = 20;
    obj.staticFunction(); // 输出 "staticVar: 20"

    return 0;
}

6.类成员初始化 

初始化列表(书上似乎写的不全)

class Person {
public:

	传统方式初始化
	//Person(int a, int b, int c) {
	//	m_A = a;
	//	m_B = b;
	//	m_C = c;
	//}

	//初始化列表方式初始化
	Person(int a, int b, int c) :m_A(a), m_B(b), m_C(c) {}
	void PrintPerson() {
		cout << "mA:" << m_A << endl;
		cout << "mB:" << m_B << endl;
		cout << "mC:" << m_C << endl;
	}
private:
	int m_A;
	int m_B;
	int m_C;
};

int main() {

	Person p(1, 2, 3);
	p.PrintPerson();


	system("pause");

	return 0;
}

7.类对象作为类成员 

C++类中的成员可以是另一个类的对象,我们称该成员为 对象成员

class A {}
class B
{
    A a;
}
  • B类中有对象A作为成员,A为对象成员
  • 那么当创建B对象时,A与B的构造和析构的顺序是谁先谁后?
    • 先调用对象成员的构造,再调用本类构造(如上例中,先调用A的构造函数)
    • 析构顺序与构造相反

7.继承

继承的好处:可以减少重复的代码

继承的语法:class 子类 : 继承方式 父类

class A : public B;

A 类称为子类 或 派生类

B 类称为父类 或 基类

继承方式

继承方式一共有三种:

  • 公共继承
  • 保护继承
  • 私有继承

总之就是,如果想要继承父类中private中的东西,就把private改成protected,这样就可以继承protected内的方法

三、文件

C++中对文件操作需要包含头文件#include < fstream >

文件类型分为两种:

文本文件 - 文件以文本的ASCII码形式存储在计算机中
二进制文件 - 文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂它们
操作文件的三大类:

ofstream:写操作
ifstream: 读操作
fstream : 读写操作

1.读取文件

  1. 包含头文件

    #include <fstream>

  2. 创建流对象

    ifstream ifs;

  3. 打开文件并判断文件是否打开成功

    ifs.open(“文件路径”,打开方式);

  4. 读数据

  5. 关闭文件

    ifs.close();

读取一个数据文件如下图代码

#include <iostream>
#include <fstream>  // 包含文件操作的头文件
#include <string>   // 包含字符串类的头文件
usingnamespace std;

int main() {
    ifstream file;    // 定义一个ifstream对象用于文件读取
    string line;     // 定义一个字符串用于存储读取的每一行

    // 打开文件
    file.open("example.txt", ios::in); // "example.txt" 是要读取的文件名

    // 检查文件是否成功打开
    if (!file.is_open()) {
        cout << "Unable to open file." << endl;
        return 1; // 如果文件无法打开,返回错误码
    }

    // 使用getline函数读取文件,直到文件末尾
    while (getline(file, line)) {
        // getline函数成功时返回的对象可以用于判断读取是否成功
        // 每读取一行,就输出这一行
        cout << line << std::endl;
    }

    // 关闭文件
    file.close();

    return 0; // 正常退出
}

四、期末往届真题

1.填空题

解答:(1)void A::

(2)w.max(a1,b1);

就是要定义成员函数和调用

 答:n*fact(n-1)

答:int i = 32;

a >= "A" && a<="Z"

因为小写字母比大写字母ASCII码大32

2.程序分析题 

分析:主函数中用了exchange函数,故会判断a,b,c的大小,可以知道a<b,所以执行func(a,b),也就是a和b会交换数值;此时a=89,b=12,故继续运行func(b,c),最后结果是a=89,b=56,c=12

分析:调用了my1中的set函数,所以number = 5,第一个输出5;第二个对number进行赋值,number是主函数中的变量,也就是10,所以输出10;最后一步输出3

这道题:

  • ::number 明确指出我们想要访问的是全局变量 number

 

分析:在主函数中,创造了一个名为a的对象,构造函数(11,12),表示a1=11,a2=12,调用print函数,故输出(11,12);接着创建一个类B,名为b的实例,构造函数运行,a1=31,a2=32,b1=33,b2=34;调用fun()函数,调用move(5,8)函数,a1=a1+5,a2=a2+8,第哦啊用print函数,故输出(33,34);接着调用f()函数,输出父类A中的print函数,也就是(36,40)

3.改错题 

1.要改为 p=&i,因为指针要一个地址值,&是解地址符

2.漏了using namespace std;

4.程序设计题

 我用的递归函数 你们可以自己想数学逻辑的写法

#include <iostream>
using namespace std;
//这道题重在理解题目意思 
int count(int n){
	if(n==1){
		return 1;
	}
	else if(n==2){
		return 2;
	}
	else if(n==3){
		return 3;
	}
	else{
		return count(n-1)+count(n-3);
	}
}
int main() {
    int y;  // 年份 ,学校人数 
    cin>>y;
	cout<<count(y);
    return 0;
}

 第二题建议自己写一遍再来看我的

要注意访问私有数据成员就必须在公有的成员函数里访问!

要有两个构造函数

实例化:R1 = Rectangle(al, a2);
                R2 = Rectangle(b1, b2);

或者我写的这种都可以

我调了很久bug

要注意一下 构造函数是没有类型的 成员函数必须有类型!!

类外定义要记得用::

#include<iostream>
using namespace std;
class Rectangle{
	private:
		double width,height;
	public:
		Rectangle();
		Rectangle(double,double);//带参数的构造函数 
		double GetArea();//成员函数 
};
Rectangle::Rectangle(){
	width = 10;
	height = 10;
}
Rectangle::Rectangle(double w,double h){
	width = w;
	height = h;
}
double Rectangle::GetArea(){
	return width*height;
}
int main(){
	double a1,a2,b1,b2;
	cin>>a1>>a2>>b1>>b2;
	Rectangle R1(a1,a2);
	Rectangle R2(b1,b2);
	double s1 = R1.GetArea();
	double s2 = R2.GetArea();
	cout<<s1<<endl;
	cout<<s2<<endl;
	if (s1>s2){
	cout<<"R1面积更大";}
	else if (s1<s2){
	cout<<"R2面积更大";}
	else{
	cout<<"面积相等";}
}

  • 38
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值