C++....................4
1.
using namespace std;
class mystring {
private:
char* p;
int len;
// 辅助函数:复制字符串
void copy(const char* source) {
len = strlen(source);
p = new char[len + 1];
strcpy(p, source);
}
// 辅助函数:释放内存
void release() {
if (p) {
delete[] p;
}
}
public:
// 构造函数
mystring(const char* s = "") {
copy(s);
}
// 拷贝构造函数
mystring(const mystring& other) {
copy(other.p);
}
// 析构函数
~mystring() {
release();
}
// 赋值运算符重载
mystring& operator=(const mystring& other) {
if (this != &other) {
release();
copy(other.p);
}
return *this;
}
// 加法运算符重载
mystring operator+(const mystring& other) const {
char* temp = new char[len + other.len + 1];
strcpy(temp, p);
strcat(temp, other.p);
mystring result(temp);
delete[] temp;
return result;
}
// 复合赋值运算符重载
mystring& operator+=(const mystring& other) {
char* temp = new char[len + other.len + 1];
strcpy(temp, p);
strcat(temp, other.p);
release();
copy(temp);
delete[] temp;
return *this;
}
// 下标运算符重载
char& operator[](int index) {
#include <cstring>
return p[index];
}
// 输出字符串
void show() const {
cout << p << endl;
}
};
int main() {
mystring str = "hello";
mystring ptr = "world";
str.show();
ptr.show();
str = str + ptr;
str.show();
str += ptr;
str.show();
str[0] = 'H';
str.show();
return 0;
}
2.
// 定义消息结构体
struct buf{
long mtype; // 消息类型,用于区分不同的频道
char mtext[1024]; // 消息内容
};
// 定义 Channel 类,用于表示消息队列中的特定频道
class Channel {
private:
int msgid;
long channel;
public:
Channel(int id, long ch) : msgid(id), channel(ch) {}
// 发送消息到指定频道
void send(const std::string& data) {
buf message;
message.mtype = channel;
strncpy(message.mtext, data.c_str(), sizeof(message.mtext) - 1);
message.mtext[sizeof(message.mtext) - 1] = '\0';
if (msgsnd(msgid, &message, strlen(message.mtext) + 1, 0) == -1) {
perror("msgsnd");
}
}
// 从指定频道读取消息
std::string read(int size) {
buf message;
if (msgrcv(msgid, &message, size, channel, 0) == -1) {
perror("msgrcv");
return "";
}
return std::string(message.mtext);
}
};
// 定义 Msg 类,用于封装消息队列的操作
class Msg {
private:
key_t key;
int msgid;
public:
// 构造函数,根据文件名生成消息队列的键值并创建消息队列
Msg(const std::string& filename) {
key = ftok(filename.c_str(), 'a');
if (key == -1) {
perror("ftok");
}
msgid = msgget(key, IPC_CREAT | 0666);
if (msgid == -1) {
perror("msgget");
}
}
// 重载 [] 运算符,返回指定频道的 Channel 对象
Channel operator[](long channel) {
return Channel(msgid, channel);
}
};
int main() {
// 创建 Msg 对象,指定文件名
Msg m("o.txt");
// 向 1 号频道发送消息
m[1].send("Hello, World!");
// 从 1 号频道读取消息
std::string str = m[1].read(1024);
std::cout << "1号频道: " << str << std::endl;
return 0;
}
3.
class Sem {
private:
key_t key;
int id;
// 辅助函数:执行信号量操作
void do_semop(int sem_num, int sem_op) {
struct sembuf sops = {static_cast<unsigned short>(sem_num), static_cast<short>(sem_op), 0};
if (::semop(id, &sops, 1) == -1) { // 使用 ::semop 调用系统函数
throw std::runtime_error("semop failed");
}
}
public:
// 构造函数:创建信号灯集,信号灯集中存在 x 个信号量,并且将所有信号量初始化为 y
Sem(int num_semaphores, int initial_value) {
key = ftok(".", 'a');
if (key == -1) {
throw std::runtime_error("ftok failed");
}
id = semget(key, num_semaphores, IPC_CREAT | 0666);
if (id == -1) {
throw std::runtime_error("semget failed");
}
for (int i = 0; i < num_semaphores; ++i) {
if (semctl(id, i, SETVAL, initial_value) == -1) {
throw std::runtime_error("semctl failed");
}
}
}
// 手动初始化信号灯集中的第 index 个信号量,初始化成 value
void init(int index, int value) {
if (semctl(id, index - 1, SETVAL, value) == -1) {
throw std::runtime_error("semctl failed");
}
}
// 重载 [] 运算符,返回一个可用于操作信号量的对象
class SemProxy {
private:
Sem& sem;
int index;
public:
SemProxy(Sem& s, int idx) : sem(s), index(idx - 1) {}
// 重载 + 和 - 运算符,让信号灯集中的第 index 个信号量的值增加或减少
SemProxy& operator+(int val) {
sem.do_semop(index, val);
return *this;
}
SemProxy& operator-(int val) {
sem.do_semop(index, -val);
return *this;
}
};
SemProxy operator[](int index) {
return SemProxy(*this, index);
}
// 析构函数:删除信号灯集
~Sem() {
if (semctl(id, 0, IPC_RMID) == -1) {
std::cerr << "Warning: semctl IPC_RMID failed" << std::endl;
}
}
};
int main() {
try {
// 创建信号灯集,包含 2 个信号量,初始值都为 5
Sem s(2, 5);
// 手动初始化信号灯集中的第 1 个信号量,初始化成 10
s.init(1, 10);
// 让信号灯集中的第 1 个信号量的值 +1
s[1] + 1;
// 让信号灯集中的第 1 个信号量的值 -1
s[1] - 1;
std::cout << "信号量操作成功" << std::endl;
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;