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); // 生成 keyid = 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; // 将消息内容存入 strreturn *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;
}