c++的坑--多线程退出,单例退出

【优秀三方库研读】【C++基础知识】odygrd/quill -- 从 ThreadContextManager 深度解析 Meyer’s Singleton(梅耶单例)模式 Meyer's Singleton 是 C++ 中最优雅、最安全的单例实现方式之一,由 C++ 大师 Scott Meyers 在《Effective C++》中提出。下面从原理到实现进行全面剖析 阅读详情

代码说明 有个单例类,有个调用主函数 ,代码主要说明使用多线程时如何正确退出。

单例类代码

#pragma once
#include <concrt.h>
class AddData
{
public:
    static AddData* Instance() {
        if (!m_pInstance)
        {
            m_pInstance = new AddData();
        }
        return m_pInstance;
    };
public:
    AddData();
    ~AddData() {};
    void StartThread();
    DWORD KeepThreadRun();
private:
    static AddData* m_pInstance;

    // 同步线程
    HANDLE  m_hKeepExitEvent;
    HANDLE  m_hKeepInfoThread;
};


#include "stdafx.h"
#include "AddData.h"
#include <winbase.h>
#include <wtypes.h>
#include <afx.h>

// 同步线程
HANDLE  m_hKeepExitEvent =NULL;
HANDLE  m_hKeepInfoThread = NULL;
AddData::AddData()
{
    m_hKeepInfoThread = NULL;
}


void AddData::StartThread()
{
    if (m_hKeepInfoThread == NULL)
    {
        DWORD dwThreadId = 0;

        m_hKeepExitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

        m_hKeepInfoThread = CreateThread(NULL, 0, KeepThreadProc, this, 0, &dwThreadId);

    }
}

DWORD  WINAPI KeepThreadProc()
{
    AddData *pInstan = AddData::Instance();
    pInstan->KeepThreadRun();



}
DWORD AddData::KeepThreadRun()
{
    ULONG uIntervalTime = 5000;

    while (true)
    {
        int iRet= WaitForSingleObject(m_hKeepExitEvent,uIntervalTime);

        if (iRet == WAIT_OBJECT_0)
        {
            TRACE("KeepThreadRun 退出");
            //TRACE 如何使用
            //1.#include <afx.h>
            //2.project->setting, 选中use MFC in a shared DLL;
            //3.project->setting->c / c++, category中选code generation, 然后在use run - time library中选debug multithreaded dll
            break;
        }
        if (iRet<0)
        {
            continue;
        }


        TRACE("KeepThreadRun runing");
        //::EnterCriticalSection( &g_criticalSection );
        //SaveData();
        //::LeaveCriticalSection(&g_criticalSection);

    }
}
// ComTest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "AddData.h"
CRITICAL_SECTION        g_criticalSection;

int main()
{

    ::InitializeCriticalSection(&g_criticalSection);

    AddData *AddDataInstance =  AddData::Instance();
    AddDataInstance->KeepThreadRun();

    Sleep(3000);

    ::DeleteCriticalSection(&g_criticalSection);
    delete AddDataInstance;

    return 0;
}

主要说两点问题
1.单例中的线程在周期性存储 调用了 公共锁,如果退出时销毁公共锁,会导致存储时崩溃。因此要先销毁单例,在析构函数中将线程关闭。

    if (m_hKeepInfoThread !=NULL)
    {
        SetEvent(m_hKeepExitEvent);
        ::WaitForSingleObject(m_hKeepInfoThread, INFINITE);
        ::CloseHandle(m_hKeepInfoThread);
        m_hKeepInfoThread = NULL;

        ::CloseHandle(m_hKeepExitEvent);
        m_hKeepExitEvent = NULL;
    }
  2 单例的析构函数一定要将 m_instance 实例置为空,否则下一次创建时,检测m_instance 不为空,不会创建新的实例,导致调用失败。
  3 注意单例类的头文件中  ~AddData() {}; 就直接实现了析构,尽量不要这样写,因为你在多数情况下要进行清理工作。
【设计模式】5. 单例模式(以及多线程、无序写入、volatile对单例的影响) 单例模式 http://www.ibm.com/developerworks/cn/java/j-dcl.html 定义:         Ensure a class has only one instance, and provide a global point of access to it.         确保某个类只有一个实例,并提供一个全局访问点。 类图: 阅读详情

相关推荐

C++ thread退出线程 多线程 子线程控制退出主线程 window VS2017 Debug Error! Abort() has been called

C++ thread退出线程 多线程 子线程控制退出主线程 window VS2017 Debug Error! Abort() has been called. C++ thread退出线程 多线程 子线程控制退出主线程 window VS2017 Debug Error! Abort() has been called.

【C/C++学习】之四种结束线程方式详解

一、四种方式 1、线程自然return返回。 如果线程能够返回,就可以确保下列事项的实现: (1)在线程函数中创建的所有C++对象均将通过它们的析构函数正确地释放。 (2)操作系统将正确地释放线程堆栈使用的内存。 (3)系统将线程的退出代码(在线程的内核对象中维护)...

醉逍遥的博客 3万+

C/C++中退出线程的四种解决方法

退出线程可以有四种方法: 1.线程函数的return返回(最好这样):其中用线程函数的return返回, 而终止线程是最安全的, 在线程函数return返回后, 会清理函数内申请的类对象, 即调用这些对象的析构函数. 然后会自动调用 _endthreadex()函数来清理 _beginthreadex(…)函数申请的资源(主要是创建的tiddata对象). 2.调用 _endthreadex()函数 或 ExitThread()函数(最好不要):如果使用这两种方法退出线程, 则不会执行线程函数的return语句, 所以就不会调用线程函数作用域内申请的类对象的析构函数, 会造成内存泄露. 剩下两

C/C++线程退出的四种方法

想要终止线程的运行,可以使用以下方法: 线程函数返回(最好使用该方法)。 同一个进程或另一个进程中的线程调用TerminateThread函数(应避免使用该方法)。 通过调用ExitThread函数,线程将自行撤消(最好不使用该方法)。 ExitProcess和TerminateProcess函数也可以用来终止线程的运行(应避免使用该方法)。 下面将详细介绍终止线程运行的方法:1-4,并说明线...

Keep Moving~ 5万+

《华为项目管理之道》第1章笔记

performance indicator,KPI)纳入个人绩效承诺书,贯彻结果导向的理念,以向员工。客户需求是华为发展的原动力,为客户服务是华为存在的唯一理由。目经理‘用兵’,依靠市场机制‘调兵’”,打破了人员在功能部门的板结,实现了听得。为管理者选拔的必要条件,项目经理成为人人向往的岗位。《华为项目管理之道》,是新出的华为官方的项目管理书,整个书不错。伴随着项目型组织的建立,华为逐步形成了完备的项目管理流程和制度,从而将业务运。为此,通过改革,重新明确了项目经理承担的经营责任,并开始以项。

jackyrongvip的专栏 2127

基于GEC6818开发板的C/C++贪吃蛇小游戏

f.开始游戏(进入游戏,并没有马上开游戏,需要点击播放才能开始)2.相关宏,全局变量(可以根据自己需要进行修改)k.显示文字前的相关初始化。k.自定义font.h文件。1.需要的主要头文件。l.在开发板上显示字1。m.在开发板上显示字2。a.显示固定大小图片。h.线程1:获得坐标。

2301_77273301的博客 2132

设计模式——C++11实现单例模式(饿汉模式、懒汉模式),与单例的进程

C++11:线程不安全、多次加锁、单次加锁、不加锁实现单例模式。介绍饿汉模式和懒汉模式。最后实现一个单例的进程

chfens的博客 1846

Spring Boot 实现多图片上传并回显,涨姿势了~

上传 Controller的代码非常简单,由于用了SpringMVC框架,所以直接用MultipartFile来接即可。由于是多图片上传所以用数组来接。此处应该注意参数名应该和<input>中的name值相对应: @RequestMapping("/pic") @ResponseBody publicResponseEntity<String>pic(MultipartFile[]pictures)throwsException{ ResponseEnti...

weixin_54556126的博客 893

C/C++四种退出线程的方法

退出线程可以有四种方法: 1.线程函数的return返回(最好这样):   其中用线程函数的return返回, 而终止线程是最安全的, 在线程函数return返回后, 会清理函数内申请的类对象, 即调用这些对象的析构函数. 然后会自动调用 _endthreadex()函数来清理 _beginthreadex(...)函数申请的资源(主要是创建的tiddata对象).

浮城大亨的专栏 3106

香橙派OPi 6系列选型指南:RK3588与RK3588S开发板深度对比

开发板选型是嵌入式系统设计的关键环节,尤其在边缘计算和AI推理等场景中,芯片的差异直接影响硬件架构。瑞芯微RK3588及其精简版RK3588S是当前高端开发板的核心方案,两者在PCIe通道、显示输出和SATA支持上存在显著区别。理解这些原理,有助于工程师根据项目需求快速匹配产品。香橙派OPi 6系列基于这两款芯片,衍生出OPi 6、OPi 6 Pro与OPi 6 Max三种形态:紧凑型适合嵌入式门禁与AI盒子,Pro版凭借双屏异显和PCIe 3.0满足收银机与视频分析,Max的双2.5G网口和大内存则面向轻

weixin_29185167的博客 227

uniapp串口通信实战:从零搭建物联网设备控制App(附完整代码)

本文详细介绍了如何使用Uniapp实现串口通信,从零搭建物联网设备控制App。内容涵盖环境配置、串口初始化、数据收发、错误处理等核心功能,并提供了完整的代码示例,帮助开发者快速掌握跨平台串口通信技术,适用于智能农业、工业自动化等物联网场景。

weixin_30369041的博客 597

【C++】C++ 单例模式总结(5种单例实现方法)

C++ 单例模式的几种实现方式。

unonoi的博客 12万+

ADRV9009学习资料保存:基于XC7Z100+ADRV9009的双收双发无线电射频板卡

ADRV9009学习资料保存:基于XC7Z100+ADRV9009的双收双发无线电射频板卡 一、板卡概述 基于XC7Z100+ADRV9009的双收双发无线电射频板卡是基于XilinxZYNQFPGA和ADI的无线收发芯片ADRV9009开发的专用功能板卡,用于5G小基站,无线图传,数据收发...

9365

C++单例进化论

private:// ✨ 如果使用成员变量形式,C++17允许inlinepublic:// ... 防止拷贝和移动🔍C++17强化inline静态成员革命 → 声明与定义合二为一,彻底告别传统C++的"声明-定义分离"噩梦(对比C++98:无需在.cpp文件单独定义→ 消除链接错误风险)基于指针的单例实现简化 → 支持延迟初始化同时保持代码优雅(传统指针方案需处理双重检查锁 + 内存屏障 → C++17可结合与智能指针实现更安全方案)

u013576331的博客 923

网络安全 | 企业网络安全的十大挑战及解决方案

网络安全 | 企业网络安全的十大挑战及解决方案,随着信息技术的飞速发展,企业数字化转型进程不断加速,网络安全问题日益成为企业运营与发展面临的关键挑战。本文深入剖析企业网络安全的十大挑战,包括网络攻击日益复杂、数据泄露风险、内部威胁、物联网安全、云安全、合规性要求、移动办公安全、供应链安全、人才短缺以及安全预算有限等,并针对每个挑战详细阐述相应的解决方案,旨在为企业构建全面、有效的网络安全体系提供指导与参考,助力企业在复杂多变的网络环境中保障自身信息资产安全,实现可持续发展。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 4万+

机器人控制基础:电机编码器常见类型

电机编码器是测量电机位置、速度和方向的传感器,主要分为光电、磁性和旋转变压器三类。光电编码器精度高但需防尘,适用于伺服系统;磁性编码器耐环境性强,常用于汽车电机;旋转变压器适应极端环境,多用于军工领域。按信号类型可分为增量式(成本低)和绝对式(断电保留位置)。选型需综合考虑精度、环境适应性及成本。

start_up_go的博客 475

【C++11】 Meyers 单例

✅ 析构由标准库在main结束后自动执行,不能手动delete实例。❌禁止在其他全局/静态对象的析构函数中获取、使用该单例,防止对象已经销毁后又复活(UB崩溃)。❌ 单例自己的析构函数内部,不要再调用。❌ C++03下多线程不安全;必须开启C++11及以上才能保证线程安全。如果业务需要可控的提前销毁,Meyers单例不适用,改用原始指针单例,自己管理 new/delete。不要保存单例的地址,在程序退出阶段去使用该地址,此时对象已经析构。

lijian2017的博客 178

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

c++单例实践

C++单例模式实践指南 本文系统介绍了C++中static关键字的多种用法,并详细讲解了单例模式的实现方法。主要内容包括: static关键字的三种作用:改变变量链接性、延长局部变量生命周期、创建类静态成员 单例模式的两种实现方式: 饿汉式:程序启动即初始化 懒汉式:首次调用时初始化 线程安全解决方案: 双重检查锁定模式(DCLP) std::call_once Meyer's Singleton(局部静态变量) 存储周期(Storage Duration)和链接性(Linkage)概念解析 文章通过代码示

weixin_55010563的博客 894

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

单例(c++)

对于单例的思考 参考: C++奇才 Andrei Alexandrescu 及其大作《Modern C++ Design》的第六章,Andrei 同时也是loki库作者和facebook folly库的核心开发人员。《Modern C++ Design》中文版为《C++设计新思维——泛型编程与设计模式之应用》,但因书籍毕竟是多年之前的作品,所以最好的参考资料是loki库源码,loki库

owen_oragen的专栏 472

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Linux下C++多线程程序的优雅退出:需求、方法与实践

在软件开发过程中,程序的退出方式直接影响着应用的稳定性和用户体验。**正常终止**指的是程序按照预定的流程完成所有任务后,有序地关闭。这通常包括释放所有分配的资源、保存必要的状态信息以及向操作系统返回成功的退出码。相反,**异常终止**则是程序在运行过程中遇到未处理的错误或异常情况,导致程序非预期地关闭。这种情况下,可能会出现资源未释放、数据损坏或系统状态不一致等问题。

探索C++编程的奥秘,分享深入的技术见解和实践,旨在激发读者创造力与解决问题的思维。 1722

设计模式——单例

1. 懒汉式单例 懒汉式单例在第一次被使用的时候才会进行实例化。 1.1 单线程的懒汉式单例 #include <iostream> using namespace std; class Singleton { private: Singleton() { cout << "Construct called!" << endl; } Singleton(Singleton&) = delete; Singleton& operator=(co

jay_zzs的博客 328

单例的学习和使用

单例模式的核心使用场景是在需要全局唯一实例、资源独占或状态共享时,避免多实例导致的资源冲突和数据不一致。懒汉单例实现中,首次调用getInstance()时才创建实例,通过私有化构造函数、禁用拷贝/赋值操作确保唯一性,并使用双重检查锁保证线程安全。关键点包括:1)私有构造函数防止外部实例化;2)禁用拷贝构造和赋值操作;3)静态指针存储唯一实例;4)双重检查锁机制确保线程安全。唯一合法创建路径是通过getInstance()方法,典型调用方式为ClassName::getInstance()->meth

2303_76638067的博客 581

C++设计模式实战:单例、工厂、观察者模式工程化应用与避坑指南

在软件工程领域,设计模式是针对常见设计问题的可复用解决方案,其核心价值在于提升代码的可维护性、可扩展性和复用性。从原理上看,设计模式通过封装变化、松耦合等原则,将复杂系统的构建模块化。在C++这类系统级编程语言中,合理运用设计模式是构建健壮、可维护的大型项目的关键技术。例如,工厂模式通过封装对象创建逻辑,实现了创建与使用的解耦,符合开闭原则;观察者模式则建立了一种松耦合的事件驱动通信机制,是构建响应式系统的基础。这些模式在GUI框架、游戏引擎、插件系统等场景中应用广泛。本文聚焦于C++工程实践,深入探讨了单

weixin_34252090的博客 628

单例分享(内存减少与循环引用解决)

分享>单例 HD中由单例引起的Bug,尤其是崩溃Bug已经不止一次了,就在周末我还在解单例相关的Bug。 单例这个问题让我想起了王健上周讲座上的一句话“我们遇到的大多数问题已经被大牛遇到过,总结过,并已经有成熟的解决问题的模式可供参考”。单例这个普通的不能再普通的设计模式,也不是例外。 我的分享很弱,其实就是引用大牛的总结并分享自己的一些心得,希望可以对单例问题的彻底解决有所帮助,虽然以下内

Owen_owen_lee的专栏 1738
上一篇: 输入网址请求网页过程
下一篇: c++的坑--字符串内存拷贝注意事项
writeeee
博客等级 码龄18年 35粉丝 76原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值