C++学习案例(一)bitset 和map的使用

bitset 和map的使用案例

需求描述

在界面中增加一个combobox,记录添加的标记值,标记值是一个有序的序列(MR,M1,M2,M3,M4),能进行添加,删除,和清空combobox中的任意值。在添加的时候一定按照序列,比如当存在MR M1 M2 M3时,先删除了M2,此时的序列为MR M1 M3,点击添加此时应该添加M2 再点击添加就是添加M4。

技术支持

bitset 用于做序列标记,这个地方可以使用array,但bitset最大的优势在于节约空间。
std::bitset<8> marker_bitset_;

map 使用map的主要作用是为了实现,枚举类型和字符串的一一对应关系。
std::map<marker_type_t, QString> marker_2_name_;

思路分析

定义一个枚举用于,记录每种标记的类型

enum class marker_type_t {
	MR = 0,M1,M2,M3,M4
};

定义两个map,来显示字符串和枚举类型的相互查找,这个地方也可以使用一个map,然后用过遍历的方式来进行字符匹配。利用second 和first方法。但是为了代码逻辑的清晰,我选择了两个map的方式:

void makerdata_update_t::initMarkers() {
		marker_2_name_[marker_type_t::MR] = u8"MR";
		marker_2_name_[marker_type_t::M1] = u8"M1";
		marker_2_name_[marker_type_t::M2] = u8"M2";
		marker_2_name_[marker_type_t::M3] = u8"M3";
		marker_2_name_[marker_type_t::M4] = u8"M4";

		for (const auto& [k, v] : marker_2_name_)
			name_2_marker_[v] = k;
}

//方法1
void makerdata_update_t::changeActiveMarker(QString markername) {
    active_marker_ = name_2_marker_[markername];
}
//方法2 
void makerdata_update_t::changeActiveMaker(QString makername) {
    for (auto it = marker_2_name_.begin(); it != marker_2_name_.end(); ++it) {

        if (!it->second.compare(makername.toUtf8()))
        {
            active_maker_ = it->first;
            break;
        }
    }
}


技术拓展

做完以后发现,在和同事沟通的时候发现c++ boost库中有“多索引”的方法。再以后的学习中,我会将这部分的代码补上。现在还没有学习到这里。

效果截图

在QML中的界面效果,点击“+”就是添加一个标记,点击“-”就是去掉当前combobox中选中的标记值,“清空”即删除所有的标记值。

在这里插入图片描述

代码附录

核心代码实现的c++类,关于QML的属性绑定,不是这次blog的关键。相关源码就不用附加上了,因为里面有很多相关的东西,不好做代码的分离。

//markerupdate.hpp
enum class marker_type_t {
	MR = 0, 
	M1,
	M2,
	M3,
	M4
};
struct makerdata_update_t :public QObject {
		Q_OBJECT
		std::map<marker_type_t, QString> marker_2_name_;
		std::map<QString, marker_type_t> name_2_marker_;
		std::bitset<8> marker_bitset_;
         Q_PROPERTY(int markerCount  READ markerCount   NOTIFY markerCountChanged);
		Q_PROPERTY(QStringList markersList   READ markersList   NOTIFY markerCountChanged);
		Q_PROPERTY(int activeMarker   READ activeMarker   NOTIFY markerCountChanged);
	public:
		makerdata_update_t(data_t&, rtsa_handle_t& rtsa);
		void initMarkers();
		int insertMarker();
		void deleteMarker();
		void clearMarker();
		QStringList markersList() {
			return getMarkersList();
		}
		int activeMarker() {
			return (int)active_marker_;
		}
		int markerCount() {
			return getMarkersCount();
		}
		void setIsLoadData(bool val) {
			is_load_data_ = val;
		}
	public:

		Q_INVOKABLE QStringList getMarkersList();
		Q_INVOKABLE void changeActiveMarker(QString);
		Q_INVOKABLE int getMarkersCount();
		Q_INVOKABLE void markerAdd();
		Q_INVOKABLE void markerDelete();
		Q_INVOKABLE void markerPeak();
		Q_INVOKABLE void markerClear();
 };
    
//markerupdate.cpp
makerdata_update_t::makerdata_update_t(data_t& data, rtsa_handle_t& rtsa){
    initMarkers();
}
void makerdata_update_t::initMarkers() {
    marker_2_name_[marker_type_t::MR] = u8"MR";
    marker_2_name_[marker_type_t::M1] = u8"M1";
    marker_2_name_[marker_type_t::M2] = u8"M2";
    marker_2_name_[marker_type_t::M3] = u8"M3";
    marker_2_name_[marker_type_t::M4] = u8"M4";

    for (const auto& [k, v] : marker_2_name_)
        name_2_marker_[v] = k;
}

QStringList makerdata_update_t::getMarkersList() {
    QStringList marker_list;
    for (std::size_t i = 0; i < marker_bitset_.size(); ++i) {
        if (marker_bitset_[i])
        {
            marker_list.append(marker_2_name_[marker_type_t(i)]);
        }
    }

    if (marker_list.count() == 0)
        marker_list.append(u8"无");
    return marker_list;
}

void makerdata_update_t::changeActiveMarker(QString markername) {
    active_marker_ = name_2_marker_[markername];
}

int makerdata_update_t::insertMarker() {
    for (std::size_t i = 0; i < (std::uint32_t)marker_type_t::M4 + 1; ++i) {
        if (!marker_bitset_[i])
        {
            marker_bitset_.set(i);
            active_marker_ = marker_type_t(i);
            break;
        }
    }			
    emit markerCountChanged();
    return (int)marker_bitset_.count();
}
void makerdata_update_t::deleteMarker() {
    if (active_marker_ == marker_type_t::MR) 
    {
        for (std::size_t i = (std::uint32_t)marker_type_t::M4 ; i >= 0; --i) {
            if (marker_bitset_[i])
            {
                marker_bitset_.reset(i);
                active_marker_ = marker_type_t(i);
                break;
            }
        }
    }else
        marker_bitset_.reset((std::uint32_t)active_marker_);

    emit markerCountChanged();
}
void makerdata_update_t::clearMarker() {
    for (std::size_t i = 0; i < (std::uint32_t)marker_type_t::M4 + 1; ++i) {
        marker_bitset_.reset(i);
        emit markerCountChanged();
    }
}

int makerdata_update_t::getMarkersCount() {
    return (int)marker_bitset_.count();
}

void makerdata_update_t::markerAdd() {
    insertMarker();
}

void makerdata_update_t::markerDelete() {
    deleteMarker();
}

void makerdata_update_t::markerClear() {
    clearMarker();
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值