प्रौद्योगिकी साझेदारी

C: मूलभूततः उन्नतपर्यन्तं एकलटनप्रतिरूपस्य डिजाइनं कार्यान्वयनञ्च

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

C++ इत्यस्मिन् एकलप्रतिमानस्य डिजाइनं कार्यान्वयनञ्च: मूलभूततः उन्नतपर्यन्तं

शीर्षकम्: C++ इत्यस्मिन् एकलप्रतिमानस्य गहनसमझः: डिजाइनः, कार्यान्वयनम्, अनुप्रयोगः च

सॉफ्टवेयरविकासे डिजाइनप्रतिमानाः विशिष्टसमस्यानां सिद्धसमाधानाः सन्ति ते विकासकानां कृते अधिकसुसंगतरूपेण, पुनःप्रयोगयोग्यरूपेण, परिपालनीयरूपेण च सॉफ्टवेयरनिर्माणे सहायकाः भवन्ति । सिंगलटन-प्रतिमानं मूलभूततमेषु व्यापकतया च प्रयुक्तेषु डिजाइन-प्रतिमानेषु अन्यतमम् अस्ति यत् एतत् सुनिश्चितं करोति यत् कस्यचित् वर्गस्य केवलम् एकः उदाहरणः भवति तथा च एतत् दृष्टान्तं प्राप्तुं वैश्विकं अभिगम-बिन्दुं प्रदाति ।अयं लेखः C++ मध्ये Singleton-प्रतिमानं कथं कार्यान्वितुं शक्यते इति गहनतया अवलोकयिष्यति, मूलभूत-कार्यन्वयनात् आरभ्य थ्रेड्-सुरक्षित-संस्करणं यावत् आधुनिक-C++-विशेषताः यथा स्मार्ट-सूचकाः तथा...std::call_once) अनुप्रयोगं, पाठकान् व्यापकं व्यावहारिकं च मार्गदर्शकं प्रदातुं प्रयतन्ते।

1. एकलप्रतिमानस्य मूलभूतसंकल्पना

एकलप्रतिमानस्य मूलविचारः अस्ति यत् कस्यचित् वर्गस्य केवलमेकं उदाहरणं भवति इति सुनिश्चितं कृत्वा वैश्विकं अभिगमबिन्दुं प्रदातुं शक्यते । यदा भवद्भिः संसाधनानाम् (यथा विन्याससञ्चिकापाठकाः, लॉगर्, दत्तांशकोशसंयोजनपूलः इत्यादयः) अभिगमनं नियन्त्रयितुं आवश्यकं भवति तदा एषः मोडः उपयोगी भवति । एकलप्रतिमानस्य कुञ्जी अस्ति : १.

  • वर्गस्य कन्स्ट्रक्टर् निजी भवति, यत् बाह्यसङ्केतः प्रत्यक्षतया वस्तुनः उदाहरणं न ददाति ।
  • वर्गस्य अन्तः एकं स्थिरं उदाहरणं प्रदातुं आवश्यकतायां एतत् उदाहरणं प्रत्यागच्छतु ।
  • स्थिरं सार्वजनिकप्रवेशविधिं प्रदातुम्, प्रायःgetInstance(), वर्गस्य एकमात्रं उदाहरणं प्राप्तुं प्रयुक्तम् ।
2. मूलभूतं कार्यान्वयनम्

प्रथमं, थ्रेड् सुरक्षाविषयेषु विचारं विना सरलं एकलप्रतिमानकार्यन्वयनं पश्यामः:

#include <iostream>

class Singleton {
private:
    // 私有构造函数,防止外部实例化
    Singleton() {}

    // 私有拷贝构造函数和赋值操作符,防止拷贝
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

    // 静态实例
    static Singleton* instance;

public:
    // 静态方法,返回类的唯一实例
    static Singleton* getInstance() {
        if (!instance) {
            instance = new Singleton();
        }
        return instance;
    }

    // 示例方法
    void doSomething() {
        std::cout << "Doing something..." << std::endl;
    }

    // 析构函数(通常是protected或public,取决于是否需要外部delete)
    ~Singleton() {
        std::cout << "Singleton destroyed." << std::endl;
    }
};

// 初始化静态实例
Singleton* Singleton::instance = nullptr;

int main() {
    Singleton* s1 = Singleton::getInstance();
    Singleton* s2 = Singleton::getInstance();

    if (s1 == s2) {
        std::cout << "s1 and s2 are the same instance." << std::endl;
    }

    s1->doSomething();
    // 注意:在多线程环境下,上述实现可能存在安全问题

    // 通常不推荐手动删除单例对象,除非有特别理由
    // delete Singleton::instance; // 谨慎使用

    return 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
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
3. सूत्रसुरक्षा कार्यान्वयनम्

बहु-सूत्र-युक्ते वातावरणे उपर्युक्त-कार्यन्वयनेन एकस्मिन् समये बहु-सूत्र-प्रवेशः भवितुम् अर्हतिgetInstance() विधिं कृत्वा बहुवारं उदाहरणानि निर्मान्ति।एतस्याः समस्यायाः समाधानार्थं वयं mutex lock (यथा...std::mutex) सूत्रसुरक्षां सुनिश्चित्य : १.

#include <mutex>
#include <iostream>

class Singleton {
private:
    Singleton() {}
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

    static Singleton* instance;
    static std::mutex mtx;

public:
    static Singleton* getInstance() {
        std::lock_guard<std::mutex> lock(mtx);
        if (!instance) {
            instance = new Singleton();
        }
        return instance;
    }

    void doSomething() {
        std::cout << "Doing something..." << std::endl;
    }

    ~Singleton() {
        std::cout << "Singleton destroyed." << std::endl;
    }
};

Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mtx;

// main函数保持不变
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
4. एकलजीवनचक्रस्य प्रबन्धनार्थं स्मार्टसूचकानाम् उपयोगं कुर्वन्तु

एकलवस्तुनः (अर्थात् प्रोग्रामस्य अन्ते स्वयमेव नष्टस्य) जीवनचक्रं स्वयमेव प्रबन्धयितुं वयं स्मार्ट-सूचकानाम् (यथाstd::unique_ptr) कच्चे सूचकानां स्थाने : १.

#include <memory>
#include <mutex>
#include <iostream>

class Singleton {
private:
    Singleton() {}
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

    static std::unique_ptr<Singleton> instance;
    static std::mutex mtx;

public:
    static Singleton& getInstance() {
        std::lock_guard<std::mutex> lock(mtx);
        if (!instance) {
            instance = std::make_unique<Singleton>();
        }
        return *instance;
    }

    void doSomething() {
        std::cout << "Doing something..." << std::endl;
    }

    // 析构函数被智能指针管理,无需手动调用
    ~Singleton() {
        std::cout << "Singleton destroyed." << std::endl;
    }

    // 禁止拷贝和移动
    Singleton(Singleton&&) = delete;
    Singleton& operator=(Singleton&&) = delete;
};

std::unique_ptr<Singleton> Singleton::instance = nullptr;
std::mutex Singleton::mtx;

int main() {
    // 注意这里返回的是引用,无需使用指针
    Singleton& s1 = Singleton::getInstance();
    Singleton& s2 = Singleton::getInstance();

    if (&s1 == &s2) {
        std::cout << "s1 and s2 are the same instance." << std::endl;
    }

    s1.doSomething();

    // 程序结束时,智能指针会自动销毁Singleton实例

    return 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
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
5. प्रयोगःstd::call_onceअनुकूलन

C++11 इत्यनेन आरभ्य, .std::call_once बहुसूत्रयुक्ते वातावरणे अपि एकवारं कार्यस्य आह्वानं भवति इति सुनिश्चित्य अधिकं कार्यक्षमं संक्षिप्तं च मार्गं प्रदाति । एकलप्रतिमानस्य कार्यान्वयनस्य अधिकं अनुकूलनार्थं वयं एतत् विशेषतां उपयोक्तुं शक्नुमः:

#include <memory>
#include <mutex>
#include <iostream>
#include <once.h> // 注意:实际上应使用#include <mutex>中的std::call_once

class Singleton {
private:
    Singleton() {}
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

    static std::unique_ptr<Singleton> instance;
    static std::once_flag onceFlag;

    static void createInstance() {
        instance = std::make_unique<Singleton>();
    }

public:
    static Singleton& getInstance() {
        std::call_once(onceFlag, createInstance);
        return *instance;
    }

    void doSomething() {
        std::cout << "Doing something..." << std::endl;
    }

    // 析构函数和移动操作符的禁用同上
};

std::unique_ptr<Singleton> Singleton::instance = nullptr;
std::once_flag Singleton::onceFlag;

// main函数保持不变
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

NOTE: उपरि कोडमध्ये अहं गलत् उद्धृतवान्#include <once.h>, वस्तुतः प्रयोगः करणीयः<mutex>शीर्षकसञ्चिकायांstd::once_flagतथाstd::call_once

6. सारांशः

एकलप्रतिरूपः C++ इत्यस्मिन् अतीव उपयोगी डिजाइनप्रतिरूपः अस्ति यत् एतत् सुनिश्चितं करोति यत् कस्यचित् वर्गस्य केवलम् एकः उदाहरणः भवति तथा च वैश्विकं अभिगमबिन्दुः प्रदाति । तथापि, एकलप्रतिरूपं कार्यान्वितुं भवद्भिः सूत्रसुरक्षाविषयेषु ध्यानं दातव्यं, विशेषतः बहुसूत्रयुक्ते वातावरणे ।म्यूटेक्स लॉक्, स्मार्ट पॉइंटर् तथा...std::call_onceआधुनिक C++ विशेषताभिः सह वयं singleton pattern अधिकं सुरक्षिततया कुशलतया च कार्यान्वितुं शक्नुमः ।

एकलप्रतिरूपस्य परिकल्पनायां भवद्भिः केचन अतिरिक्तकारकाः विचारणीयाः, यथा एकलवस्तुनः जीवनचक्रप्रबन्धनम् (कार्यक्रमस्य समाप्तेः समये स्वयमेव नष्टस्य आवश्यकता अस्ति वा), आलस्यपूर्णभारस्य अनुमतिः अस्ति वा (अर्थात् निर्माणे विलम्बः दृष्टान्तस्य यावत् प्रथमप्रयोगः न भवति) इत्यादि । तदतिरिक्तं, केषुचित् सन्दर्भेषु, भवान् एकलप्रतिरूपस्य विविधतां विचारयितुम् इच्छति, यथा बहु-दृष्टान्तप्रतिमानं (यत् वर्ग-दृष्टान्तानां संख्यां नियन्त्रयति, परन्तु निश्चितां उच्चसीमायाः अतिक्रमणं न करोति) अथवा सन्दर्भ-आधारित-एकल-प्रतिरूपं ( यत् भिन्नसन्दर्भाधारितं भिन्नानि मूल्यानि प्रत्यागच्छति)।

आशासे यत् एषः लेखः पाठकान् C++ मध्ये एकलप्रतिमानं अधिकतया अवगन्तुं वास्तविकपरियोजनासु लचीलतया उपयोगं कर्तुं च साहाय्यं कर्तुं शक्नोति।