search
HomeBackend DevelopmentC#.Net TutorialImplementation of Singleton class in C++

In "Design Pattern", Singleton is written as a return pointer:

class Singleton{
public:
    static Singleton* Instance();
protected:
    Singleton();
private:
    static Singleton* _instance;
};

The corresponding implementation cpp file is:

Singleton* Singleton::_instance;
Singleton* Singleton::Instance(){
    if( _instance == 0){
        _instance = new Singleton;
    };
    return _instance;
}

The purpose of designing the constructor as protected is to prevent new outside the class. Some people may design it as private. If you consider If it is possible to inherit this class, it is better to design the constructor as protected, and also need to add a virtual destructor. To prevent others from copying the Singleton object:

Singleton* pSingleton = Singleton::Instance();
Singleton s1 = *pSingleton;
Singleton s2 = *pSingleton; 
需要将拷贝构造(copy constructor)函数变成 private。

But the question here is, when to delete the Singleton object? According to a basic principle of C++, the object is destroyed wherever it is created. There should also be a destroy method here to delete the Singleton object. It will be more troublesome if you forget to delete it. The Instance function also has the locking problem of simultaneous access by multiple threads. If locking and unlocking are placed at the beginning and end of the Instance function, the performance of the entire function will drop a lot. This is not a good design.
There is a small change that can avoid the memory leak problem caused by forgetting to delete the Singleton object. That is to use std:auto_ptr to contain the Singleton object, define a class static member auto_ptr object, and automatically delete the Singleton object when the static auto_ptr variable is destructed. In order to prevent users from deleting Singleton objects, the destructor needs to be changed from public to protected. The following is the header file SingletonAutoPtr.h:

#include <memory>
using namespace std;
class CSingletonAutoPtr 
{
private:
    static auto_ptr<CSingletonAutoPtr> m_auto_ptr;
    static CSingletonAutoPtr* m_instance;
protected:
    CSingletonAutoPtr();
    CSingletonAutoPtr(const CSingletonAutoPtr&);
    virtual ~CSingletonAutoPtr(); 
    //allow auto_ptr to delete, using protected ~CSingletonAutoPtr()
    friend class auto_ptr<CSingletonAutoPtr>; 
public:
    static CSingletonAutoPtr* GetInstance();
    void Test();
};

#p# corresponds to SingletonAutoPtr.cpp as follows:

#include "SingletonAutoPtr.h"
#include <iostream>
//initial static member vars here 
CSingletonAutoPtr* CSingletonAutoPtr::m_instance = NULL;
auto_ptr<CSingletonAutoPtr> CSingletonAutoPtr::m_auto_ptr;
/////////////////////////////////////////
// Construction/Destruction
/////////////////////////////////////////
CSingletonAutoPtr::CSingletonAutoPtr()
{
    cout << "CSingletonAutoPtr::CSingletonAutoPtr()" << endl;
    //put single object into auto_ptr object 
    m_auto_ptr = auto_ptr<CSingletonAutoPtr>(this);
}
CSingletonAutoPtr::~CSingletonAutoPtr()
{
    cout << "CSingletonAutoPtr::~CSingletonAutoPtr()" << endl;
}
CSingletonAutoPtr* CSingletonAutoPtr::GetInstance()
{
    //begin lock
    //....
    if(m_instance == NULL)
        m_instance = new CSingletonAutoPtr();
    //end lock
    //...
    return m_instance;
    }
void CSingletonAutoPtr::Test()
{
    cout << "CSingletonAutoPtr::Test()" << endl;
}

Calling method:

CSingletonAutoPtr* pSingleton = CSingletonAutoPtr::GetInstance();
pSingleton->Test();

Writing a Singleton in C++ requires so much effort, which is beyond our expectation. There are many people who have never used auto_ptr, and std:auto_ptr itself is not perfect. It is based on the object ownership mechanism. In contrast, there is an auto_ptr in Apache Log4cxx, which is based on object counting and is easier to use. Having to use log4cxx just to use a good auto_ptr is not good for many projects. Of course, std:auto_ptr in ANSI C++'s STL is sufficient for writing the above example.

#p#Another idea is that it may be better to design the GetInstance function as a static member, because generally speaking, Singleton objects are not large. Although static members must always occupy memory, it is not a big problem. The destructor here must be set to public. The following is the header file SingleStaticObj.h

class CSingletonStaticObj 
{
private:
    static CSingletonStaticObj m_instance;
protected:
    CSingletonStaticObj();
    CSingletonStaticObj(const CSingletonStaticObj&);
public:
    virtual ~CSingletonStaticObj(); //must public
    static CSingletonStaticObj& GetInstance();
    void Test();
};
    对应的 SingleStaticObj.cpp 文件为:
#include "SingletonStaticObj.h"
#include <string>
#include <iostream>

using namespace std;
CSingletonStaticObj CSingletonStaticObj::m_instance;
CSingletonStaticObj::CSingletonStaticObj()
{
    cout << "CSingletonStaticObj::CSingletonStaticObj()" << endl;
}
CSingletonStaticObj::~CSingletonStaticObj()
{
    cout << "CSingletonStaticObj::~CSingletonStaticObj()" << endl;
}
CSingletonStaticObj& CSingletonStaticObj::GetInstance()
{
    return m_instance;
}
void CSingletonStaticObj::Test()
{
    cout << "CSingletonStaticObj::Test()" << endl;
}

The calling method:

CSingletonStaticObj& singleton = CSingletonAutoPtr::GetInstance();singleton.Test();

In terms of code size, it seems that using static member ref is simpler. I prefer this method.

However, static member singleton is not suitable in all situations. For example, GetInstance cannot be used when it needs to dynamically decide to return different instances. For example, FileSystem::GetInstance may need to return new WinFileSystem when running under Windows, and may need to return new LinuxFileSystem when running under Linux/Unix. In this case, you still need to use the above auto_ptr method containing a singleton pointer.


Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Developing with C# .NET: A Practical Guide and ExamplesDeveloping with C# .NET: A Practical Guide and ExamplesMay 12, 2025 am 12:16 AM

C# and .NET provide powerful features and an efficient development environment. 1) C# is a modern, object-oriented programming language that combines the power of C and the simplicity of Java. 2) The .NET framework is a platform for building and running applications, supporting multiple programming languages. 3) Classes and objects in C# are the core of object-oriented programming. Classes define data and behaviors, and objects are instances of classes. 4) The garbage collection mechanism of .NET automatically manages memory to simplify the work of developers. 5) C# and .NET provide powerful file operation functions, supporting synchronous and asynchronous programming. 6) Common errors can be solved through debugger, logging and exception handling. 7) Performance optimization and best practices include using StringBuild

C# .NET: Understanding the Microsoft .NET FrameworkC# .NET: Understanding the Microsoft .NET FrameworkMay 11, 2025 am 12:17 AM

.NETFramework is a cross-language, cross-platform development platform that provides a consistent programming model and a powerful runtime environment. 1) It consists of CLR and FCL, which manages memory and threads, and FCL provides pre-built functions. 2) Examples of usage include reading files and LINQ queries. 3) Common errors involve unhandled exceptions and memory leaks, and need to be resolved using debugging tools. 4) Performance optimization can be achieved through asynchronous programming and caching, and maintaining code readability and maintainability is the key.

The Longevity of C# .NET: Reasons for its Enduring PopularityThe Longevity of C# .NET: Reasons for its Enduring PopularityMay 10, 2025 am 12:12 AM

Reasons for C#.NET to remain lasting attractive include its excellent performance, rich ecosystem, strong community support and cross-platform development capabilities. 1) Excellent performance and is suitable for enterprise-level application and game development; 2) The .NET framework provides a wide range of class libraries and tools to support a variety of development fields; 3) It has an active developer community and rich learning resources; 4) .NETCore realizes cross-platform development and expands application scenarios.

Mastering C# .NET Design Patterns: From Singleton to Dependency InjectionMastering C# .NET Design Patterns: From Singleton to Dependency InjectionMay 09, 2025 am 12:15 AM

Design patterns in C#.NET include Singleton patterns and dependency injection. 1.Singleton mode ensures that there is only one instance of the class, which is suitable for scenarios where global access points are required, but attention should be paid to thread safety and abuse issues. 2. Dependency injection improves code flexibility and testability by injecting dependencies. It is often used for constructor injection, but it is necessary to avoid excessive use to increase complexity.

C# .NET in the Modern World: Applications and IndustriesC# .NET in the Modern World: Applications and IndustriesMay 08, 2025 am 12:08 AM

C#.NET is widely used in the modern world in the fields of game development, financial services, the Internet of Things and cloud computing. 1) In game development, use C# to program through the Unity engine. 2) In the field of financial services, C#.NET is used to develop high-performance trading systems and data analysis tools. 3) In terms of IoT and cloud computing, C#.NET provides support through Azure services to develop device control logic and data processing.

C# .NET Framework vs. .NET Core/5/6: What's the Difference?C# .NET Framework vs. .NET Core/5/6: What's the Difference?May 07, 2025 am 12:06 AM

.NETFrameworkisWindows-centric,while.NETCore/5/6supportscross-platformdevelopment.1).NETFramework,since2002,isidealforWindowsapplicationsbutlimitedincross-platformcapabilities.2).NETCore,from2016,anditsevolutions(.NET5/6)offerbetterperformance,cross-

The Community of C# .NET Developers: Resources and SupportThe Community of C# .NET Developers: Resources and SupportMay 06, 2025 am 12:11 AM

The C#.NET developer community provides rich resources and support, including: 1. Microsoft's official documents, 2. Community forums such as StackOverflow and Reddit, and 3. Open source projects on GitHub. These resources help developers improve their programming skills from basic learning to advanced applications.

The C# .NET Advantage: Features, Benefits, and Use CasesThe C# .NET Advantage: Features, Benefits, and Use CasesMay 05, 2025 am 12:01 AM

The advantages of C#.NET include: 1) Language features, such as asynchronous programming simplifies development; 2) Performance and reliability, improving efficiency through JIT compilation and garbage collection mechanisms; 3) Cross-platform support, .NETCore expands application scenarios; 4) A wide range of practical applications, with outstanding performance from the Web to desktop and game development.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

VSCode Windows 64-bit Download

VSCode Windows 64-bit Download

A free and powerful IDE editor launched by Microsoft

MantisBT

MantisBT

Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.