C++....................4

发布于:2025-02-25 ⋅ 阅读:(17) ⋅ 点赞:(0)

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;


网站公告

今日签到

点亮在社区的每一天
去签到