c++数据测试

SafeQueue.h

#pragma once
#include <iostream>
#include <string>
#include <cstring>
 #include <queue>
 #include <unistd.h>
 #include <mutex>
 #include <condition_variable>
#include <pthread.h>


template <typename T>
class SafeQueue {
public:
    using lock_type = std::unique_lock<std::mutex>;
public:
    SafeQueue() = default;
    // 手动添加拷贝构造
    SafeQueue(const SafeQueue& other)
    {
        // std::lock_guard<std::mutex> lock(other.mutex_);
        lock_type lock{mutex_};
        queue_ = other.queue_;
    }
    ~SafeQueue() = default;
    template<typename IT>
    void push(IT &&item) {
        static_assert(std::is_same<T, std::decay_t<IT>>::value, "Item type is not convertible!!!");
        {
        lock_type lock{mutex_};
        queue_.emplace(std::forward<IT>(item));
        }
        cv_.notify_one();
    }
    auto pop() -> T {
        lock_type lock{mutex_};
        cv_.wait(lock, [&]() { return !queue_.empty(); });
        auto front = std::move(queue_.front());
        queue_.pop();
        return front;
    }

    // - `empty()`:检查队列是否为空。
    // 通过创建互斥锁对象,锁定临界区并使用STL `queue::empty()` 成员函数检查元素是否为空来实现。
    bool empty() const {
        lock_type lock{mutex_};
        return queue_.empty();
    }

    // - `size()`:返回队列中元素的数量。
    // 通过创建互斥锁对象,锁定临界区并使用STL `queue::size()` 成员函数返回队列中元素的数量来实现。
    size_t size() const {
        lock_type lock{mutex_};
        return queue_.size();
    }
    
    // - `swap()`:用另一个队列对象交换这个队列对象的内容。
    // 由于交换操作涉及两个不同的队列对象,因此需要创建两个互斥锁对象分别锁定两个队列对象,
    // 然后使用STL `queue::swap()` 成员函数在两个队列对象之间交换内容来实现。
    void swap(SafeQueue<T>& other) {
        lock_type lock1{mutex_, std::defer_lock};
        lock_type lock2{other.mutex_, std::defer_lock};
        std::lock(lock1, lock2);
        std::swap(queue_, other.queue_);
    }

    // - `clear()`:清空队列中的所有元素。
    // 通过创建互斥锁对象,锁定临界区并使用STL `queue::swap()` 成员函数在队列对象中交换备用队列来实现。
    void clear() {
        lock_type lock{mutex_};
        std::queue<T>().swap(queue_);
    }

private:
    std::queue<T> queue_;
    mutable std::mutex mutex_;
    // std::mutex mutex_;
    std::condition_variable cv_;
};

DataBase.h

#pragma once
#include <iostream>
#include <string>
#include <cstring>
#include <sstream>
#include <mutex>
#include <vector>
#include "SafeQueue.h"

using namespace std;

template<typename T>
using SafeQueue2D = SafeQueue<SafeQueue<T>>;
SafeQueue2D<int> testQ;

void init()
{
    for (int i = 0; i < 5; i++)
    {
        SafeQueue<int> row;
        for (int j = 0; j < 5; j++)
        {
            row.push(j + i * 5);
        }
        testQ.push(row);
    }
    
}

void print()
{
    init();
    std::ostringstream ss;
    while (!testQ.empty()) {
        auto row = testQ.pop();
        while (!row.empty()) {
            ss << row.pop() << " ";
        }
        ss << '\n'; // 一行结束
    }
    std::cout << ss.str() << std::endl;
}





template <typename T>
class DataBase {
public:
    DataBase() {
        // m_queue.
    }
    // T & getData(int type) const;
    // template <typename T>
    T& getData(int type) const {
        if(type == m_ulinkMsgType) {
            if(!m_dataulink.empty()) {
                return m_dataulink.back();
            } else {
                throw std::out_of_range("No data available for requested type");
            }
        } else if(type == m_dlinkMsgType) {
            if(!m_datadlink.empty()) {
                return m_datadlink.back();
            } else {
                throw std::out_of_range("No data available for requested type");
            }
        } else {
            throw std::invalid_argument("Invalid data type");
        }
    }
    
    // setData(int type, const T &data);
    void setData(int type, const T &data) {
        if(type == m_ulinkMsgType) {
            m_dataulink.push_back(data);
        } else if(type == m_dlinkMsgType) {
            m_datadlink.push_back(data);
        } else {
            throw std::invalid_argument("Invalid data type");
        }
    }

public:
    static SafeQueue<SafeQueue<T>> m_queue;
    static vector<T> m_dataulink;
    static vector<T> m_datadlink;
    static int m_ulinkMsgType;
    static int m_dlinkMsgType;
    // std::mutex m_mutex;
};


// 声明模板类中的静态成员变量
template <typename T>
SafeQueue<SafeQueue<T>> DataBase<T>::m_queue;
template <typename T>
vector<T> DataBase<T>::m_dataulink;
template <typename T>
vector<T> DataBase<T>::m_datadlink;
template <typename T>
int DataBase<T>::m_ulinkMsgType = 1;
template <typename T>
int DataBase<T>::m_dlinkMsgType = 2;

Config.h


#pragma once
#include <iostream>

typedef enum tag_enum_ulink_ {
    DB_ULINK_TYPE0 = 0,
    DB_ULINK_TYPE1,
    DB_ULINK_TYPE2,
    DB_ULINK_TYPE3,
    DB_ULINK_TYPE4,
    DB_ULINK_TYPE5,
} ULinkDataType;

typedef enum tag_enum_dlink_ {
    DB_DLINK_TYPE0 = 0,
    DB_DLINK_TYPE1,
    DB_DLINK_TYPE2,
    DB_DLINK_TYPE3,
    DB_DLINK_TYPE4,
    DB_TYPE5,
} DLinkDataType;

main.c

#include <iostream>
#include <string>
#include <cstring>
#include "DataBase.h"
#include "Config.h"

int main()
{

    std::cout << "hello c++" << std::endl;

    // DataBase<int> db;
    // db.m_queue[0].push(1);
    print();


    try {
        // 创建一个DataBase类的实例化对象 string类型
        DataBase<std::string> db;

        // 设置向量中的数据
        db.setData(DataBase<std::string>::m_ulinkMsgType, "this is a string for ulink Msg.");
        db.setData(DataBase<std::string>::m_dlinkMsgType, "this is a string for dlink Msg.");

        // 获取并输出向量中的数据
        std::cout << db.getData(DataBase<std::string>::m_ulinkMsgType) << std::endl; // 输出:this is a string for ulink Msg.
        std::cout << db.getData(DataBase<std::string>::m_dlinkMsgType) << std::endl; // 输出:this is a string for dlink Msg.

        // 尝试获取一个不存在的数据类型会抛出异常
        db.getData(3);  // 输出:Invalid data type
    } catch(const std::exception &e) {
        std::cerr << "Error: " << e.what() << std::endl;
    }


    return 0;
}






测试结果:

hello c++
0 1 2 3 4 
5 6 7 8 9 
10 11 12 13 14 
15 16 17 18 19 
20 21 22 23 24 

this is a string for ulink Msg.
this is a string for dlink Msg.
Error: Invalid data type

根据上述声明,可以实现`getData()`和`setData()`方法的代码如下:

```c++
template <typename T>
T& DataBase<T>::getData(int type) const {
    if(type == m_ulinkMsgType) {
        if(!m_dataulink.empty()) {
            return m_dataulink.back();
        } else {
            throw std::out_of_range("No data available for requested type");
        }
    } else if(type == m_dlinkMsgType) {
        if(!m_datadlink.empty()) {
            return m_datadlink.back();
        } else {
            throw std::out_of_range("No data available for requested type");
        }
    } else {
        throw std::invalid_argument("Invalid data type");
    }
}

template <typename T>
void DataBase<T>::setData(int type

, const T &data) {
    if(type == m_ulinkMsgType) {
        m_dataulink.push_back(data);
    } else if(type == m_dlinkMsgType) {
        m_datadlink.push_back(data);
    } else {
        throw std::invalid_argument("Invalid data type");
    }
}
```

`getData()`方法接受一个整数类型参数,表示要获取的数据类型。如果请求的数据类型为`m_ulinkMsgType`或`m_dlinkMsgType`(存储在静态成员变量中),则分别尝试从`m_dataulink`或`m_datadlink`向量的末尾获取数据,并返回。如果所请求的向量为空则抛出异常。

`setData()`方法接受要设置的数据及其类型参数。如果类型参数为`m_ulinkMsgType`或`m_dlinkMsgType`,则向对应的向量中插入数据。

以下是一个示例,展示如何使用`DataBase`类并测试其实现:

```c++
#include <iostream>
#include <string>
#include <vector>
#include <stdexcept>
#include "DataBase.h"

// 声明模板类中的静态成员变量
template <typename T>
SafeQueue<SafeQueue<T>> DataBase<T>::m_queue;
template <typename T>
vector<T> DataBase<T>::m_dataulink;
template <typename T>
vector<T> DataBase<T>::m_datadlink;
template <typename T>
int DataBase<T>::m_ulinkMsgType = 1;
template <typename T>
int DataBase<T>::m_dlinkMsgType = 2;

int main() {

    try {
        // 创建一个DataBase类的实例化对象 string类型
        DataBase<std::string> db;

        // 设置向量中的数据
        db.setData(DataBase<std::string>::m_ulinkMsgType, "this is a string for ulink Msg.");
        db.setData(DataBase<std::string>::m_dlinkMsgType, "this is a string for dlink Msg.");

        // 获取并输出向量中的数据
        std::cout << db.getData(DataBase<std::string>::m_ulinkMsgType) << std::endl; // 输出:this is a string for ulink Msg.
        std::cout << db.getData(DataBase<std::string>::m_dlinkMsgType) << std::endl; // 输出:this is a string for dlink Msg.

        // 尝试获取一个不存在的数据类型会抛出异常
        db.getData(3);  // 输出:Invalid data type
    } catch(const std::exception &e) {
        std::cerr << "Error: " << e.what() << std::endl;
    }

    return 0;
}
```

在这个示例中,我们首先创建了一个`DataBase<std::string>`的实例化对象,并将两个字符串存储到`m_dataulink`和`m_datadlink`向量中,分别使用`setData()`来设置这两个向量中的数据。

然后我们使用`getData()`方法分别获取这两个向量中的数据,并打印结果。最后,我们测试获取一个不存在的类型时是否引发异常。如果存在异常,则捕获并在标准错误流上输出。

需要注意的是,这个示例只测试了`DataBase`类的`setData()`和`getData()`方法,实际上,这里也只有`整数int`类型一个成员变量,而使用时,需要根据实际情况进行更多类型的测试。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值