当前位置: 首页 > news >正文

网站整体迁移该怎么做局域网建设直播网站

网站整体迁移该怎么做,局域网建设直播网站,免费网页模板之家,wordpress密码文件夹前面的文章已经实现了许多QObject的功能了#xff1a; C实现一个简单的Qt信号槽机制 C实现简化版Qt信号槽机制#xff08;2#xff09;#xff1a;增加内存安全保障 C实现简化版Qt的QObject#xff08;3#xff09;#xff1a;增加父子关系、属性系统 但是#xff0c;…前面的文章已经实现了许多QObject的功能了 C实现一个简单的Qt信号槽机制 C实现简化版Qt信号槽机制2增加内存安全保障 C实现简化版Qt的QObject3增加父子关系、属性系统 但是Qt中还有一个关键的功能是事件系统。 为了让我们的QObject也支持事件系统我们可以设计一套简单实用的事件机制。 设计事件循环 事件系统离不开事件循环截止到C 20标准库里没有一套官方的事件循环机制可能是因为实现一个事件循环也不是什么难事吧。 为了简化我们的事件循环机制我们用到了一个c11引入的独特的容器priority_queue 。它提供了一个严格的弱序列其中每个元素都有一个优先级。在 priority_queue 中元素被按优先级排序最高优先级的元素总是位于队列的前端。我们将事件循环的时间按执行时间点的远近作为优先级可以很好地简化排序逻辑。 结合boost::asio和qt的EventLoop的使用经验我计划这个简单实用的事件循环使用的姿势如下 refl::CEventLoop loop; loop.post([]() {std::cout Immediate task\n;});//马上执行loop.post([]() {std::cout Delayed task\n;}, std::chrono::seconds(1));//延时一秒std::thread loop_thread([loop]() {loop.run();});std::this_thread::sleep_for(std::chrono::seconds(2)); loop.stop();//停止消息循环 loop_thread.join();实现事件循环 在确定使用方法之后总体的接口和功能实现就比较简单了。 核心成员变量和函数功能注释如下 class CEventLoop {std::priority_queueTimedHandler tasks_;//成员变量任务队列std::mutex mutex_;//用于等待相关std::condition_variable cond_;//用于等待相关std::atomicbool running_{ true };//标识是否正在运行// post 函数用于提交一个待执行的任务到事件循环中。// 参数 handler 是一个函数对象代表需要异步执行的任务。// 参数 delay 表示任务延迟执行的时间默认是立即执行Duration::zero()。void post(Handler handler, Duration delay Duration::zero()) {// 对互斥量上锁保证线程安全。std::unique_lockstd::mutex lock(mutex_);// 将任务和它应该被执行的时间点现在 延迟一起存入优先级队列中。tasks_.push({Clock::now() delay, std::move(handler)});// 通知一个等待中的线程如果有的话有新的任务已经被提交。cond_.notify_one();}// run 函数启动事件循环循环内部不断地执行任务。void run() {// 只要 running_ 标志为 true事件循环就会继续运行。while (running_) {// 对互斥量上锁保证线程安全。std::unique_lockstd::mutex lock(mutex_);// 如果当前没有任务可执行就等待直到有新任务被提交或者事件循环被停止。if (tasks_.empty()) {cond_.wait(lock, [this] { return !tasks_.empty() || !running_; });}// 当有任务可以执行时优先级队列中最早的任务时间 当前时间执行它们。while (!tasks_.empty() tasks_.top().first Clock::now()) {// 从队列中取出任务。auto task std::move(tasks_.top());// 将任务从队列中移除。tasks_.pop();// 释放互斥量锁以便其他线程可以提交任务或者修改任务队列。lock.unlock();// 执行任务。task.second();// 任务执行完毕后再次上锁互斥量。lock.lock();}// 如果队列中还有任务等待直到队列中最早的任务到达执行时间。if (!tasks_.empty()) {// 等待直到最早任务的执行时间或者条件变量被通知。cond_.wait_until(lock, tasks_.top().first);}}} }; 虽然几十行代码实现的时间循环非常精简但是也不能少了扩展能力通过扩展可以实现更复杂的主消息循环等复杂场景。于是我们引入一个回调类IEventLoopHost class IEventLoopHost {public:virtual void onWaitForTask(std::condition_variable cond, std::unique_lockstd::mutex locker) 0;virtual void onEvent(TimedHandler event) 0;virtual void onWaitForRun(std::condition_variable cond, std::unique_lockstd::mutex locker, const TimePoint timePoint) 0;};在特定时机可以通过回调类替换掉默认实现从而实现完整的功能扩展。 事件循环的完整代码 后续放到github上迭代https://github.com/kevinyangli/simple_qt_qobject.git class CEventLoop { public:using Clock std::chrono::steady_clock;using TimePoint Clock::time_point;using Duration Clock::duration;using Handler std::functionvoid();struct TimedHandler {TimePoint time;Handler handler;bool operator(const TimedHandler other) const {return time other.time;}};class IEventLoopHost {public:virtual void onWaitForTask(std::condition_variable cond, std::unique_lockstd::mutex locker) 0;virtual void onEvent(TimedHandler event) 0;virtual void onWaitForRun(std::condition_variable cond, std::unique_lockstd::mutex locker, const TimePoint timePoint) 0;}; private:IEventLoopHost* host nullptr;std::priority_queueTimedHandler tasks_;std::mutex mutex_;std::condition_variable cond_;std::atomicbool running_{ true };public:void setHost(IEventLoopHost* host) {this-host host;}void post(Handler handler, Duration delay Duration::zero()) {std::unique_lockstd::mutex lock(mutex_);tasks_.push({ Clock::now() delay, std::move(handler) });cond_.notify_one();}void run() {while (running_) {std::unique_lockstd::mutex lock(mutex_);if (tasks_.empty()) {if (host) {host-onWaitForTask(cond_, lock);}else {cond_.wait(lock, [this] { return !tasks_.empty() || !running_; });}}while (!tasks_.empty() tasks_.top().time Clock::now()) {auto task tasks_.top();tasks_.pop();lock.unlock();if (host) {host-onEvent(task);}else {task.handler();}lock.lock();}if (!tasks_.empty()) {if (host) {host-onWaitForRun(cond_, lock, tasks_.top().time);}else {cond_.wait_until(lock, tasks_.top().time);}}}}void stop() {running_ false;cond_.notify_all();}};带上完整的测试代码以及之前的功能实现 #include iostream #include tuple #include stdexcept #include assert.h #include string_view #include optional #include utility // For std::forward #include unordered_map #include functional #include memory #include any #include type_traits // For std::is_invocable #include map#include chrono #include thread #include vector #include queue #include mutex #include condition_variable #include atomicnamespace refl {// 这个宏用于创建字段信息 #define REFLECTABLE_PROPERTIES(TypeName, ...) using CURRENT_TYPE_NAME TypeName; \static constexpr auto properties_() { return std::make_tuple(__VA_ARGS__); } #define REFLECTABLE_MENBER_FUNCS(TypeName, ...) using CURRENT_TYPE_NAME TypeName; \static constexpr auto member_funcs() { return std::make_tuple(__VA_ARGS__); }// 这个宏用于创建属性信息并自动将字段名转换为字符串 #define REFLEC_PROPERTY(Name) refl::Propertydecltype(CURRENT_TYPE_NAME::Name), CURRENT_TYPE_NAME::Name(#Name) #define REFLEC_FUNCTION(Func) refl::Functiondecltype(CURRENT_TYPE_NAME::Func), CURRENT_TYPE_NAME::Func(#Func)// 定义一个属性结构体存储字段名称和值的指针template typename T, T Valuestruct Property {const char* name;constexpr Property(const char* name) : name(name) {}constexpr T get_value() const { return Value; }};template typename T, T Valuestruct Function {const char* name;constexpr Function(const char* name) : name(name) {}constexpr T get_func() const { return Value; }};// 使用 std::any 来处理不同类型的字段值和函数返回值template typename T, typename Tuple, size_t N 0std::any __get_field_value_impl(T obj, const char* name, const Tuple tp) {if constexpr (N std::tuple_size_vTuple) {return std::any();// Not Found!}else {const auto prop std::getN(tp);if (std::string_view(prop.name) name) {return std::any(obj.*(prop.get_value()));}else {return __get_field_value_implT, Tuple, N 1(obj, name, tp);}}}// 使用 std::any 来处理不同类型的字段值和函数返回值template typename T, size_t N 0std::any get_field_value(T* obj, const char* name) {return obj ? __get_field_value_impl(*obj, name, T::properties_()) : std::any();}// 使用 std::any 来处理不同类型的字段值和函数返回值template typename T, typename Tuple, typename Value, size_t N 0std::any __assign_field_value_impl(T obj, const char* name, const Value value, const Tuple tp) {if constexpr (N std::tuple_size_vTuple) {return std::any();// Not Found!}else {const auto prop std::getN(tp);if (std::string_view(prop.name) name) {if constexpr (std::is_assignable_vdecltype(obj.*(prop.get_value())), Value) {obj.*(prop.get_value()) value;return std::any(obj.*(prop.get_value()));}else {assert(false);// 无法赋值 类型不匹配!!return std::any();}}else {return __assign_field_value_implT, Tuple, Value, N 1(obj, name, value, tp);}}}template typename T, typename Valuestd::any assign_field_value(T* obj, const char* name, const Value value) {return obj ? __assign_field_value_impl(*obj, name, value, T::properties_()) : std::any();}// 成员函数调用相关:template bool assert_when_error true, typename T, typename FuncTuple, size_t N 0, typename... Argsconstexpr std::any __invoke_member_func_impl(T obj, const char* name, const FuncTuple tp, Args... args) {if constexpr (N std::tuple_size_vFuncTuple) {assert(!assert_when_error);// 没找到return std::any();// Not Found!}else {const auto func std::getN(tp);if (std::string_view(func.name) name) {if constexpr (std::is_invocable_vdecltype(func.get_func()), T, Args...) {if constexpr (std::is_voiddecltype(std::invoke(func.get_func(), obj, std::forwardArgs(args)...))::value) {// 如果函数返回空那么兼容这种casestd::invoke(func.get_func(), obj, std::forwardArgs(args)...);return std::any();}else {return std::invoke(func.get_func(), obj, std::forwardArgs(args)...);}}else {assert(!assert_when_error);// 调用参数不匹配return std::any();}}else {return __invoke_member_func_implassert_when_error, T, FuncTuple, N 1(obj, name, tp, std::forwardArgs(args)...);}}}template typename T, typename... Argsconstexpr std::any invoke_member_func(T* obj, const char* name, Args... args) {constexpr auto funcs T::member_funcs();return obj ? __invoke_member_func_impl(obj, name, funcs, std::forwardArgs(args)...) : std::any();}template typename T, typename... Argsconstexpr std::any invoke_member_func_safe(T* obj, const char* name, Args... args) {constexpr auto funcs T::member_funcs();return obj ? __invoke_member_func_impltrue(obj, name, funcs, std::forwardArgs(args)...) : std::any();}template typename T, typename FuncPtr, typename FuncTuple, size_t N 0constexpr const char* __get_member_func_name_impl(FuncPtr func_ptr, const FuncTuple tp) {if constexpr (N std::tuple_size_vFuncTuple) {return nullptr; // Not Found!}else {const auto func std::getN(tp);if constexpr (std::is_same decltype(func.get_func()), FuncPtr ::value) {return func.name;}else {return __get_member_func_name_implT, FuncPtr, FuncTuple, N 1(func_ptr, tp);}}}template typename T, typename FuncPtrconstexpr const char* get_member_func_name(FuncPtr func_ptr) {constexpr auto funcs T::member_funcs();return __get_member_func_name_implT, FuncPtr(func_ptr, funcs);}// 定义一个类型特征模板用于获取属性信息template typename Tstruct For {static_assert(std::is_class_vT, Reflector requires a class type.);// 遍历所有字段名称template typename Funcstatic void for_each_propertie_name(Func func) {constexpr auto props T::properties_();std::apply([](auto... x) {((func(x.name)), ...);}, props);}// 遍历所有字段值template typename Funcstatic void for_each_propertie_value(T* obj, Func func) {constexpr auto props T::properties_();std::apply([](auto... x) {((func(x.name, obj-*(x.get_value()))), ...);}, props);}// 遍历所有函数名称template typename Funcstatic void for_each_member_func_name(Func func) {constexpr auto props T::member_funcs();std::apply([](auto... x) {((func(x.name)), ...);}, props);}};// // 以下是动态反射机制的支持代码namespace dynamic {// 反射基类class IReflectable : public std::enable_shared_from_thisIReflectable {public:virtual ~IReflectable() default;virtual std::string_view get_type_name() const 0;virtual std::any get_field_value_by_name(const char* name) const 0;virtual std::any invoke_member_func_by_name(const char* name) 0;virtual std::any invoke_member_func_by_name(const char* name, std::any param1) 0;virtual std::any invoke_member_func_by_name(const char* name, std::any param1, std::any param2) 0;virtual std::any invoke_member_func_by_name(const char* name, std::any param1, std::any param2, std::any param3) 0;virtual std::any invoke_member_func_by_name(const char* name, std::any param1, std::any param2, std::any param3, std::any param4) 0;// 不能无限增加会增加虚表大小。最多支持4个参数的调用。};// 类型注册工具class TypeRegistry {public:using CreatorFunc std::functionstd::shared_ptrIReflectable();static TypeRegistry instance() {static TypeRegistry registry;return registry;}void register_type(const std::string_view type_name, CreatorFunc creator) {creators_[type_name] std::move(creator);}std::shared_ptrIReflectable create(const std::string_view type_name) {if (auto it creators_.find(type_name); it ! creators_.end()) {return it-second();}return nullptr;}private:std::unordered_mapstd::string_view, CreatorFunc creators_;};// 用于注册类型信息的宏 #define DECL_DYNAMIC_REFLECTABLE(TypeName) \friend class refl::dynamic::TypeRegistryEntryTypeName; \static std::string_view static_type_name() { return #TypeName; } \virtual std::string_view get_type_name() const override { return static_type_name(); } \static std::shared_ptr::refl::dynamic::IReflectable create_instance() { return std::make_sharedTypeName(); } \static const bool is_registered; \std::any get_field_value_by_name(const char* name) const override { \return refl::get_field_value(this, name); \} \std::any invoke_member_func_by_name(const char* name) override { \return refl::invoke_member_func(static_castTypeName*(this), name); \}\std::any invoke_member_func_by_name(const char* name, std::any param1) override { \return refl::invoke_member_func(static_castTypeName*(this), name, param1); \}\std::any invoke_member_func_by_name(const char* name, std::any param1, std::any param2) override { \return refl::invoke_member_func(static_castTypeName*(this), name, param1, param2); \}\std::any invoke_member_func_by_name(const char* name, std::any param1, std::any param2, std::any param3) override { \return refl::invoke_member_func(static_castTypeName*(this), name, param1, param2, param3); \}\std::any invoke_member_func_by_name(const char* name, std::any param1, std::any param2, std::any param3, std::any param4) override { \return refl::invoke_member_func(static_castTypeName*(this), name, param1, param2, param3, param4); \}\ // 用于在静态区域注册类型的辅助类template typename Tclass TypeRegistryEntry {public:TypeRegistryEntry() {::refl::dynamic::TypeRegistry::instance().register_type(T::static_type_name(), T::create_instance);}};// 为每个类型定义注册变量这段宏需要出现在cpp中。 #define REGEDIT_DYNAMIC_REFLECTABLE(TypeName) \const bool TypeName::is_registered [] { \static ::refl::dynamic::TypeRegistryEntryTypeName entry; \return true; \}();}//namespace dynamic//宏用于类中声明信号并提供一个同名的方法来触发信号。宏参数是函数参数列表。示例/* void x_value_modified(int param) {IMPL_SIGNAL(param);}*/ #define REFLEC_IMPL_SIGNAL(...) raw_emit_signal_impl(__func__ , __VA_ARGS__)class CObject :public refl::dynamic::IReflectable {private:// 信号与槽的映射键是信号名称值是一组槽函数的信息using connections_list_type std::liststd::tuple std::weak_ptrIReflectable, std::string;using connections_type std::unordered_mapstd::string, connections_list_type;connections_type connections_;public:templatetypename... Argsvoid raw_emit_signal_impl(const char* signal_name, Args... args) {auto it connections_.find(signal_name);if (it ! connections_.end()) {auto slots it-second; // 获取槽信息列表的引用bool has_invalid_slot false;for (const auto slot_info : slots) {auto ptr std::get0(slot_info).lock(); // 锁定弱引用if (ptr) {ptr-invoke_member_func_by_name(std::get1(slot_info).c_str(), std::forwardArgs(args)...);}else {has_invalid_slot true;}}if (has_invalid_slot) {//如果存在无效对象则执行一轮移除操作auto remove_it std::remove_if(slots.begin(), slots.end(),[](const auto slot_info) {return std::get0(slot_info).expired(); // 检查弱引用是否失效});slots.erase(remove_it, slots.end());}}else {/*没找到这个信号要不要assert*/ }}auto connect(const char* signal_name, refl::CObject* slot_instance, const char* slot_member_func_name) {if (!slot_instance || !signal_name || !slot_member_func_name) {throw std::runtime_error(param is null!);}assert(slot_instance-weak_from_this().lock());//target必须通过make_share构造因为要弱引用它std::string str_signal_name(signal_name);auto itMap connections_.find(str_signal_name);if (itMap ! connections_.end()) {itMap-second.emplace_back(slot_instance-weak_from_this(), slot_member_func_name);//必须插入末尾因为返回了--end()迭代器指示这个链接return std::make_optional(std::make_tuple(this, itMap, --itMap-second.end()));}else {// 如果没找到插入新元素到map中并获取迭代器auto emplace_result connections_.emplace(std::make_pair(std::move(str_signal_name), connections_list_type()));itMap emplace_result.first;itMap-second.emplace_back(slot_instance-weak_from_this(), slot_member_func_name);return std::make_optional(std::make_tuple(this, itMap, --itMap-second.end()));}}template typename SlotClassauto connect(const char* signal_name, std::shared_ptrSlotClass slot_instance, const char* slot_member_func_name) {return connect(signal_name, slot_instance.get(), slot_member_func_name);}template typename SignalClass, typename SignalType, typename SlotClass, typename SlotTypeauto connect(SignalType SignalClass::* signal, SlotClass* slot_instance, SlotType SlotClass::* slot) {const char* signal_name get_member_func_nameSignalClass(signal);const char* slot_name get_member_func_nameSlotClass(slot);if (signal_name slot_name) {return connect(signal_name, static_castCObject*(slot_instance), slot_name);}throw std::runtime_error(signal name or slot_name is not found!);}template typename SignalClass, typename SignalType, typename SlotClass, typename SlotTypeauto connect(SignalType SignalClass::* signal, std::shared_ptrSlotClass slot_instance, SlotType SlotClass::* slot) {return connect(signal, slot_instance.get(), slot);}template typename Tbool disconnect(T connection) {//T是个这个类型std::make_optional(std::make_tuple(this, itMap, it)); 由于T过于复杂就直接用模板算了if (!connection) {return false;}auto tuple connection.value();if (std::get0(tuple) ! this) {return false;//不是我的connection呀}std::get1(tuple)-second.erase(std::get2(tuple));return true;}};class QObject : public CObject {private:std::string objectName_;std::weak_ptrrefl::dynamic::IReflectable parent_;std::unordered_mapstd::string, std::any properties_;std::liststd::shared_ptrrefl::dynamic::IReflectable children_;public:void setObjectName(const char* name) {objectName_ name;}const std::string getObjectName() {return objectName_;}void setParent(QObject* newParent) {if (auto oldParent dynamic_castQObject*(parent_.lock().get())) {auto it std::find_if(oldParent-children_.begin(), oldParent-children_.end(),[this](const auto child) { return child.get() this; });if (it ! oldParent-children_.end()) {oldParent-children_.erase(it);}}if (newParent) {parent_ newParent-weak_from_this();newParent-children_.push_back(shared_from_this());}else {parent_.reset();}}template typename Tvoid setParent(std::shared_ptrT newParent) {setParent(newParent.get());}void removeChild(CObject* child) {auto ch static_castrefl::dynamic::IReflectable*(child);auto it std::find_if(children_.begin(), children_.end(),[this, ch](const auto child) { return child.get() ch; });if (it ! children_.end()) {children_.erase(it);}}CObject* findChild(const char* name) {for (auto child : children_) {QObject* qChild dynamic_castQObject*(child.get());if (qChild qChild-objectName_ name) {return qChild;}}return nullptr;}CObject* findChildRecursively(const char* name) {for (auto child : children_) {QObject* qChild dynamic_castQObject*(child.get());if (qChild) {if (qChild-objectName_ name) {return qChild;}CObject* found qChild-findChildRecursively(name);if (found) {return found;}}}return nullptr;}const std::any getProperty(const char* name) {return properties_[name];}templatetypename Tconst T* getProperty(const char* name) {try {return std::any_castconst T(properties_[name]);}catch (...) {return nullptr;}}void setProperty(const char* name, const std::any value) {properties_[name] value;}};class CEventLoop {public:using Clock std::chrono::steady_clock;using TimePoint Clock::time_point;using Duration Clock::duration;using Handler std::functionvoid();struct TimedHandler {TimePoint time;Handler handler;bool operator(const TimedHandler other) const {return time other.time;}};class IEventLoopHost {public:virtual void onWaitForTask(std::condition_variable cond, std::unique_lockstd::mutex locker) 0;virtual void onEvent(TimedHandler event) 0;virtual void onWaitForRun(std::condition_variable cond, std::unique_lockstd::mutex locker, const TimePoint timePoint) 0;};private:IEventLoopHost* host nullptr;std::priority_queueTimedHandler tasks_;std::mutex mutex_;std::condition_variable cond_;std::atomicbool running_{ true };public:void setHost(IEventLoopHost* host) {this-host host;}void post(Handler handler, Duration delay Duration::zero()) {std::unique_lockstd::mutex lock(mutex_);tasks_.push({ Clock::now() delay, std::move(handler) });cond_.notify_one();}void run() {while (running_) {std::unique_lockstd::mutex lock(mutex_);if (tasks_.empty()) {if (host) {host-onWaitForTask(cond_, lock);}else {cond_.wait(lock, [this] { return !tasks_.empty() || !running_; });}}while (!tasks_.empty() tasks_.top().time Clock::now()) {auto task tasks_.top();tasks_.pop();lock.unlock();if (host) {host-onEvent(task);}else {task.handler();}lock.lock();}if (!tasks_.empty()) {if (host) {host-onWaitForRun(cond_, lock, tasks_.top().time);}else {cond_.wait_until(lock, tasks_.top().time);}}}}void stop() {running_ false;cond_.notify_all();}};}// namespace refl// 一下为使用示例代码// 用户自定义的结构体 class MyStruct ://public refl::dynamic::IReflectable // 如果不需要动态反射可以不从public refl::dynamic::IReflectable派生public refl::QObject // 这里我们也测试信号槽等功能因此从这个类派生 {public:~MyStruct() {std::cout getObjectName() destoryed std::endl;}int x{ 10 };double y{ 20.5f };int print() const {std::cout MyStruct::print called! x: x , y: y std::endl;return 666;}// 如果需要支持动态调用参数必须是std::any并且不能超过4个参数。int print_with_arg(std::any param) const {std::cout MyStruct::print called! arg is: std::any_castint(param) std::endl;return 888;}// 定义一个方法用作槽函数必须在REFLECTABLE_MENBER_FUNCS列表中不支持返回值并且参数必须是std::any不能超过4个参数。std::any on_x_value_modified(std::any new_value) {int value std::any_castint(new_value);std::cout MyStruct::on_x_value_modified called! New value is: value std::endl;return 0;}void x_value_modified(std::any param) {REFLEC_IMPL_SIGNAL(param);}REFLECTABLE_PROPERTIES(MyStruct,REFLEC_PROPERTY(x),REFLEC_PROPERTY(y));REFLECTABLE_MENBER_FUNCS(MyStruct,REFLEC_FUNCTION(print),REFLEC_FUNCTION(print_with_arg),REFLEC_FUNCTION(on_x_value_modified),REFLEC_FUNCTION(x_value_modified));DECL_DYNAMIC_REFLECTABLE(MyStruct)//动态反射的支持如果不需要动态反射可以去掉这行代码 };//动态反射注册类注册创建工厂 REGEDIT_DYNAMIC_REFLECTABLE(MyStruct)int main() {// 静态反射部分std::cout ---------------------静态反射部分 std::endl;auto obj std::make_sharedMyStruct();// 打印所有字段名称refl::ForMyStruct::for_each_propertie_name([](const char* name) {std::cout Field name: name std::endl;});// 打印所有字段值refl::ForMyStruct::for_each_propertie_value(obj.get(), [](const char* name, auto value) {std::cout Field name has value: value std::endl;});// 打印所有函数名称refl::ForMyStruct::for_each_member_func_name([](const char* name) {std::cout Member func name: name std::endl;});// 获取特定成员的值如果找不到成员则返回默认值auto x_value refl::get_field_value(obj.get(), x);std::cout Field x has value: std::any_castint(x_value) std::endl;auto y_value refl::get_field_value(obj.get(), y);std::cout Field y has value: std::any_castdouble(y_value) std::endl;//修改值refl::assign_field_value(obj.get(), y, 33.33f);y_value refl::get_field_value(obj.get(), y);std::cout Field y has modifyed,new value is: std::any_castdouble(y_value) std::endl;auto z_value refl::get_field_value(obj.get(), z); // z 不存在if (z_value.type().name() std::string_view(int)) {std::cout Field z has value: std::any_castint(z_value) std::endl;}// 通过字符串调用成员函数 printauto print_ret refl::invoke_member_func_safe(obj.get(), print);std::cout print member return: std::any_castint(print_ret) std::endl;std::cout ---------------------动态反射部分 std::endl;// 动态反射部分(动态反射完全不需要知道类型MyStruct的定义)// 动态创建 MyStruct 实例并调用方法auto instance refl::dynamic::TypeRegistry::instance().create(MyStruct);if (instance) {std::cout Dynamic instance type: instance-get_type_name() std::endl;// 这里可以调用 MyStruct 的成员方法auto x_value2 instance-get_field_value_by_name(x);std::cout Field x has value: std::any_castint(x_value2) std::endl;instance-invoke_member_func_by_name(print);instance-invoke_member_func_by_name(print_with_arg, 10);//instance-invoke_member_func_by_name(print_with_arg, 20, 222);//这个调用会失败命中断言因为print_with_arg只接受一个函数}// 信号槽部分std::cout ---------------------信号槽部分 std::endl;auto obj1 std::make_sharedMyStruct();obj1-setObjectName(obj1);auto obj2 std::make_sharedMyStruct();obj2-setObjectName(obj2);obj2-setParent(obj1);// 连接obj1的信号到obj2的槽函数auto connection_id obj1-connect(x_value_modified, obj2.get(), on_x_value_modified);if (!connection_id) {std::cout Signal x_value_modified from obj1 connected to on_x_value_modified slot in obj2. std::endl;}obj1-x_value_modified(42);// 触发信号// 断开连接obj1-disconnect(connection_id);// 再次触发信号应该没有任何输出因为已经断开连接obj1-x_value_modified(84);// 使用成员函数指针版本的connectconnection_id obj1-connect(MyStruct::x_value_modified, obj2, MyStruct::on_x_value_modified);if (!connection_id) {std::cout Signal connected to slot. std::endl;}obj1-x_value_modified(666);// 触发信号obj2.reset();obj1.reset();// 事件循环部分std::cout ---------------------事件循环部分 std::endl;refl::CEventLoop loop;loop.post([]() {std::cout Immediate task\n;});//马上执行loop.post([]() {std::cout Delayed task\n;}, std::chrono::seconds(1));//延时一秒std::thread loop_thread([loop]() {loop.run();});std::this_thread::sleep_for(std::chrono::seconds(2));loop.stop();//停止消息循环loop_thread.join();std::cout end std::endl;return 0; }
http://www.hkea.cn/news/14340297/

相关文章:

  • 北京建站公司兴田德润很好公司网站 seo
  • 什么网站做问卷好自适应网站建设模板
  • 宏泰机械网站建设WordPress推荐中文插件
  • 做网站用什么语言简单用WordPress做一个落地页
  • 深圳 响应式网站建设wordpress完整虚拟资源下载类源码
  • 新建网站怎么做优化网站推广办法
  • 东莞营销网站建设多少钱企业网站续费
  • 旅游网站的建设内容Wordpress卡片主题
  • 陕西做网站找谁wordpress 文字链接
  • 建设一个营销型网站山西省住房与城乡建设厅网站
  • 可以查企业的网站ui设计是什么工作
  • 回收手表的网站网站设计论文经济可行性分析
  • 广州多语言外贸网站建设支付网站建设会计分录
  • 聊城网站推广品牌wordpress主题虚拟资源交易平台
  • 爱站关键词查询安阳网站制作优化
  • 网站打赏怎么做的注册装修公司要多少钱才能注册
  • 网站不见了门禁考勤网站建设
  • 自建网站怎么做后台管理系统360信息流广告在哪里展示
  • 邢台好蜘蛛网站建设专业做红木家具网站
  • 石家庄网站建设外包网站编辑知识
  • 义乌网站建站移动互联网应用程序管理情况
  • 神一般的网页设计网站网络平台推广
  • 手机网站备案泰安人才招聘网最新招聘2023
  • 切片工具做网站怎么做安卓手机应用开发
  • 企业网站备案不通过网站和系统哪个好做
  • 源码网站wordpress标签设置主页
  • 厦门网站建设_wordpress 手机看不了视频
  • 射阳建设网站多少钱陕西网站建设开发
  • 查询网站备案时间甘谷县建设局网站
  • 深圳网站建设公司服务平台怎么样可以自己做网站