当前位置: 首页 > news >正文

C++ day5 练习

一、练习1

        编写一个长方形类;

        私有成员: a, b

        构造函数初始化;

        set、get 接口;

        编写一个正方形类,继承自长方形类;

        构造函数初始化;

        无论如何,正方形类对象总是正方形的;

【代码】:

#include <iostream>

using namespace std;

class ABAB{
private:
	int a;
	int b;
public:
	ABAB(int a=0, int b=0):a(a), b(b){}
	void setA(int l){a = l;}
	void setB(int l){b = l;}
	int getA(){return a;}
	int getB(){return b;}
};

class AABB:public ABAB{
public:
	AABB(int a=0, int b=0)
		:ABAB(a, b)
	{}

	void setA(int a){
		ABAB::setA(a);
		ABAB::setB(a);
	}

	void setB(int b){
		ABAB::setA(b);
		ABAB::setB(b);
	}
};

int main()
{
	AABB aabb;
	aabb.setA(5);
	aabb.setB(5);

	cout << "a=" << aabb.getA() << endl;
	cout << "b=" << aabb.getB() << endl;

	return 0;
}


二、练习2

        写一个三角形类,拥有私有成员;

                a,b,c 三条边

        写好构造函数初始化 abc 以及 abc 的set、get 接口;

        再写一个等腰三角形类,继承自三角形类:

                1、写好构造函数,初始化三条边;

                2、要求无论如何,等腰三角形类对象,总是等腰的;

        再写一个等边三角形类,继承自等腰三角形类;

                1、写好构造函数,初始化三条边;

                2、要求无论如何,等腰三角形类对象,总是等边;

【代码】:

#include <iostream>

using namespace std:

class ABC{
private:
	int a;
	int b;
	int c;
public:
	ABC(int a=0; int b=0; int c=0):a(a), b(b), c(c){}
	void setA(int l){a = l;}
	void setB(int l){b = l;}
	void setC(int l){c = l;}
	int getA(){return a;}
	int getB(){return b;}
	int getC(){return c;}
};

class AAC:public ABC{
public:
	AAB(int ab=0; int c=0)
		:ABC(ab, ab, c)
	{}

	void setA(int a){
		ABC::setA(a);
		ABC::setB(a);
	}

	void setB(int b){
		ABC::setA(b);
		ABC::setB(b);
	}
};


class AAA:public AAC{
public:
	AAA(int ab=0, int ac=0, int bc=0)
		:AAC(ab, ac, bc)
	{}

	void setA(int a){
		AAC::setA(a);
		AAC::setB(a);
		AAC::setC(a);
	}

	void setB(int b){
		AAC::setA(b);
		AAC::setB(b);
		AAC::setC(b);
	}

	void setC(int c){
		AAC::setA(c);
		AAC::setB(c);
		AAC::setC(c);
	}
};

int main()
{
	AAA aaa;
	aaa.setA(5);
	aaa.setB(5);
	aaa.setC(5);

	cout << "a=" << aaa.getA() << endl;
	cout << "b=" << aaa.getB() << endl;
	cout << "c=" << aaa.getC() << endl;

	return 0;
}


三、练习3

        封装消息队列

        class Msg{

                key_t key;

                int id;

                int channel;

        }

        实现以下功能:

        Msg m("文件名");

        m[1].send("数据");  // 将数据发送到1号频道中;

        string str = m[1].recv(int size);  // 从1号频道中读取消息,并且返回;

        把 send 改成 operator<< , recv 改成 operator>>

        实现效果:

                m[1] << "helloworld";  // 将 "helloworld" 写入消息队列的1号频道中;

                m[1] >> str; // 读取消息队列中1频道中的消息,存入 str 中;

        编写程序测试。

【代码】:

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h>

using namespace std;

class Msg {
private:
    key_t key;
    int id;
    int channel;

    // 消息结构体
    struct msgbuf {
        long channel; // 消息类型(频道)
        char text[512]; // 消息内容
    };

public:
    // 构造函数
    Msg(const string& filename = "") {
        key = ftok(filename.data(), 1); // 生成 key
        id = msgget(key, IPC_CREAT | 0666); // 创建消息队列
        if (id == -1) {
            perror("msgget");
            exit(EXIT_FAILURE);
        }
    }

    // 析构函数
    ~Msg() {
        msgctl(id, IPC_RMID, 0); // 删除消息队列
    }

    // 重载 << 运算符,用于发送消息
    Msg& operator<<(const string& str) {
        msgbuf buf = {0};
        strncpy(buf.text, str.data(), sizeof(buf.text) - 1); // 复制消息内容
        buf.channel = channel; // 设置消息频道
        if (msgsnd(id, &buf, strlen(buf.text) + 1, 0) == -1) { // 发送消息
            perror("msgsnd");
        }
        return *this;
    }

    // 重载 >> 运算符,用于接收消息
    Msg& operator>>(string& str) {
        msgbuf buf = {0};
        if (msgrcv(id, &buf, sizeof(buf.text), channel, 0) == -1) { // 接收消息
            perror("msgrcv");
        }
        str = buf.text; // 将消息内容存入 str
        return *this;
    }

    // 重载 [] 运算符,用于设置频道
    Msg& operator[](int channel) {
        this->channel = channel; // 设置当前频道
        return *this;
    }
};

int main() {
    Msg m; // 创建消息队列对象

    // 向 1 号频道发送消息
    m[1] << "helloworld";

    // 从 1 号频道接收消息
    string str;
    m[1] >> str;
    cout << "Received message: " << str << endl;

    return 0;
}


四、练习4

        封装信号灯集

        class Sem{

                key_t key;

                int id;

                int index

        }

        实现以下功能:

        Sem s(参数x,参数y); // 创建信号灯集,信号灯集中存在 x 个信号量,并且将所有信号量初始化为 y;

        s[1].init(10); // 手动初始化信号灯集中的第1个信号量,初始化成 10;

        s[1] + 1;  // 让信号灯集中的第1个信号量的值 +1;

        s[1].operator+(1) s[1] - 1;  // 让信号灯集中的第1个信号量的值 -1;

        追加 operator ++ 功能,即解锁一次;

        以及 operator-- 功能, 即上锁一次;

【代码】:

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <sstream>
#include <vector>
#include <memory>
#include <sys/ipc.h>
#include <sys/sem.h>

using namespace std;

class Sem {
private:
    key_t key;
    int id;
    int index;
public:
    Sem(const string& filename = "", int n, int val) {
        key = ftok(filename.data(), 'R');
        id = semget(key, n, IPC_CREAT | 0666);
        for (int i = 0; i < n; i++) {
            semctl(id, i, SETVAL, val);
        }
    }

    ~Sem() {
        semctl(id, 0, IPC_RMID);
    }

    Sem& operator++() { // 前置++
        sembuf buf = {};
        buf.sem_num = index;
        buf.sem_op = 1;
        buf.sem_flg = SEM_UNDO;
        semop(id, &buf, 1);
        return *this;
    }

    Sem& operator--() { // 前置--
        sembuf buf = {};
        buf.sem_num = index;
        buf.sem_op = -1;
        buf.sem_flg = SEM_UNDO;
        semop(id, &buf, 1);
        return *this;
    }

    friend Sem& operator+(const Sem& l, int val);
    friend Sem& operator-(const Sem& l, int val);
    friend Sem& operator[](const Sem& l, int index);
};

Sem& operator+(const Sem& l, int val) {
    sembuf buf = {};
    buf.sem_num = l.index;
    buf.sem_op = abs(val);
    buf.sem_flg = SEM_UNDO;
    semop(l.id, &buf, 1);
    return const_cast<Sem&>(l);
}

Sem& operator-(const Sem& l, int val) {
    sembuf buf = {};
    buf.sem_num = l.index;
    buf.sem_op = -abs(val);
    buf.sem_flg = SEM_UNDO;
    semop(l.id, &buf, 1);
    return const_cast<Sem&>(l);
}

Sem& operator[](const Sem& l, int index) {
    const_cast<Sem&>(l).index = index;
    return const_cast<Sem&>(l);
}

int main(int argc, const char** argv) {
    Sem sem("semfile", 1, 1); // 创建一个信号量,初始值为1

    // 测试 operator++
    cout << "Unlocking semaphore..." << endl;
    ++sem;
    cout << "Semaphore unlocked." << endl;

    // 测试 operator--
    cout << "Locking semaphore..." << endl;
    --sem;
    cout << "Semaphore locked." << endl;

    return 0;
}


相关文章:

  • QT:paintEvent、QPainter、QPaintDevice
  • Matlab——图像保存导出成好看的.pdf格式文件
  • 存储引擎、索引(MySQL笔记第四期)
  • 指令模型VS推理模型
  • 复现win7永恒之蓝漏洞
  • angular日历
  • 常用视频格式及其编码方式对比
  • CORS:跨域访问、如何在Nginx中配置允许跨域访问
  • UE的TreeView组件使用
  • 2025-2-24-4.9 单调栈与单调队列(基础题)
  • 计算机毕业设计Hadoop+Spark+DeepSeek-R1大模型民宿推荐系统 hive民宿可视化 民宿爬虫 大数据毕业设计(源码+文档+PPT+讲解)
  • steam_api.dll丢失3分钟修复指南,解决Steam游戏无法运行
  • STM32 HAL库0.96寸OLED显示液晶屏
  • 图解感知机(Perceptron)
  • Linux与自动化的基础
  • 2025年02月24日Github流行趋势
  • 解决鼠标唤醒关屏状态下的笔记本
  • leetcode 207. 课程表
  • Qt基础之四十九:Qt属性系统(Property System)
  • 【学习笔记】LLM+RL
  • 交通运输局男子与两名女子办婚礼?官方通报:未登记结婚,开除该男子
  • 学生靠老干妈下饭、职工餐肉类又多又好?纪委出手整治
  • 央媒:设施老化、应急预案套模板,养老机构消防隐患亟待排查
  • 15年全免费,内蒙古准格尔旗实现幼儿园到高中0学费
  • 中国纪检监察刊文:力戒形式主义官僚主义关键是要坚持实事求是
  • 精品消费“精”在哪?多在体验上下功夫