2.24 c++练习(继承)

 1:编写一个长方形类,
私有成员 a,b
构造函数初始化
set get 接口

编写一个正方形类,继承自长方形类
    构造函数初始化
    无论如何,正方形类对象总是正方形的

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <sstream>
#include <vector>
#include <memory>
 
using namespace std;                 
 
class Rectangle{
private:
	int a;//长
	int b;//宽
public:
	Rectangle(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 Square:public Rectangle{
public:
	Square(int k=0):Rectangle(k,k){}
	void setA(int a){
		Rectangle::setA(a);
		Rectangle::setB(a);
	}
 
	void setB(int a){
		Rectangle::setA(a);
		Rectangle::setB(a);
	}
};
 
int main(int argc,const char** argv){
	Square g;//正方形对象
	g.setA(5);
	cout << g.getA() << " " << g.getB() << endl;
	g.setB(6);
	cout << g.getA() << " " << g.getB() << endl;
}

写一个三角形类,拥有私有成员
    a,b,c 三条边
2. 写好构造函数初始化 abc 以及 abc 的set get 接口

再写一个等腰三角形类,继承自三角形类
    1:写好构造函数,初始化三条边
    2:要求无论如何,等腰三角形类对象,总是等腰的
    
再写一个等边三角形类,继承自等腰三角形类
    1:写好构造函数,初始化三条边
    2:要求无论如何,等腰三角形类对象,总是等边

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <sstream>
#include <vector>
#include <memory>
 
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:
	AAC(int ab=0,int c=0):ABC(ab,ab,c){}
 
	void setA(int a){
		ABC::setA(a);
		ABC::setB(a);
	}
 
	void setB(int a){
		ABC::setA(a);
		ABC::setB(a);
	}
};
 
class AAA:public AAC{
public:
	AAA(int abc=0):AAC(abc,abc){}
 
	void setA(int a){
		AAC::setA(a);
		ABC::setC(a);
	}
 
	void setB(int a){
		AAC::setA(a);
		ABC::setC(a);
	}
 
	void setC(int a){
		AAC::setA(a);
		ABC::setC(a);
	}
};
 
int main(int argc,const char** argv){
	AAC aac;
	aac.setA(4);
	cout << aac.getA() << " " << aac.getB() << " " << aac.getC() << endl;
	aac.setB(5);
	cout << aac.getA() << " " << aac.getB() << " " << aac.getC() << endl;
	aac.setC(6);
	cout << aac.getA() << " " << aac.getB() << " " << aac.getC() << endl;
 
	AAA aaa;
	aaa.setA(3);
	cout << aaa.getA() << " " << aaa.getB() << " " << aaa.getC() <<endl;
	aaa.setB(4);
	cout << aaa.getA() << " " << aaa.getB() << " " << aaa.getC() <<endl;
	aaa.setC(5);
	cout << aaa.getA() << " " << aaa.getB() << " " << aaa.getC() <<endl;
}

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 <sys/ipc.h>
#include <sys/msg.h>
#include <cstring>

using namespace std;

class Msg {
private:
    key_t key;
    int id;

    struct Msgbuf {
        long channel;
        char buf[128];
    };

public:
    // 子类:Channel
    class Channel {
    private:
        int id;
        long channel;

    public:
        Channel(int msg_id, long ch) : id(msg_id), channel(ch) {}

        // 重载 operator<< 发送数据
        void operator<<(const string &data) {
            Msgbuf msg;
            msg.channel = channel;
            strncpy(msg.buf, data.c_str(), 127);  
            msg.buf[127] = '\0';  

            if (msgsnd(id, &msg, strlen(msg.buf) + 1, 0) == -1) {
                perror("msgsnd");
            }
        }

        // 重载 operator>> 接收数据
        void operator>>(string &data) {
            Msgbuf msg;
            memset(&msg, 0, sizeof(msg));

            if (msgrcv(id, &msg, sizeof(msg.buf), channel, IPC_NOWAIT) == -1) {
                perror("msgrcv");
                data = "";
                return;
            }
            data = string(msg.buf);
        }
    };

    // 构造函数
    Msg() {
        key = ftok("./ipc", 2);
        if (key == -1) {
            perror("ftok failed");
            exit(1);
        }

        id = msgget(key, IPC_CREAT | 0666);
        if (id == -1) {
            perror("msgget failed");
            exit(1);
        }
    }

    // 重载 operator[] 返回 Channel 对象
    Channel operator[](int ch) {
        return Channel(id, ch);
    }
};


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

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

    // 从 1 号频道读取消息
    string str;
    m[1] >> str;

    cout << "Received: " << 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-- 功能, 即上锁一次

编写程序测试

封装信号灯集
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/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(), 1);
        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);
    }

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

    // operator++ 解锁一次
    friend Sem& operator++(Sem& l, int) {
        sembuf buf = {0};
        buf.sem_num = l.index;
        buf.sem_op = 1;   // 解锁一次
        buf.sem_flg = SEM_UNDO;
        semop(l.id, &buf, 1);
        return l;
    }

    // operator-- 上锁一次
    friend Sem& operator--(Sem& l, int) {
        sembuf buf = {0};
        buf.sem_num = l.index;
        buf.sem_op = -1;  // 上锁一次
        buf.sem_flg = SEM_UNDO;
        semop(l.id, &buf, 1);
        return l;
    }
};

// Sem s
// s + 1解锁
// s - 1 上锁
// s + 1 + 1 + 1 - 2 - 3
// int(4) + 3
Sem& operator+(const Sem& l, int val) {
    sembuf buf = {0};
    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 = {0};
    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) {
    Sem temp = l;  // 创建一个副本,因为我们不能修改const对象
    temp.index = index;
    return temp;
}

int main() {
    Sem s("semfile", 1, 1);  // 创建一个信号量,初值为1

    // 测试解锁和加锁
    s[0] + 1;  // 解锁一次
    s[0] - 1;  // 上锁一次
    s[0]++;    // 解锁一次
    s[0]--;    // 上锁一次

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值