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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值