如何实现对象的克隆?如何实现单例模式?

时间:2024-12-20 07:47:50

实现对对象的克隆

移动构造(移动语义实现的):通过移动语义实现移动构造,旧对象的资源的拥有权转移给新对象

拷贝构造 :通过旧对象初始化新对象,可能会存在浅拷贝和深拷贝的问题

赋值运算符:把一个对象的属性赋值给另一个对象,实现对前一个对象的拷贝

自定义一个clone方法:对于基类和派生类的层次结构,定义一个虚函数 clone(),在派生类中重写该函数,以确保多态克隆。

#include <iostream>
#include <string>

class Base {
public:
    virtual ~Base() {}
    virtual Base* clone() const = 0;
    virtual void display() const = 0;
};


class Derived : public Base {
private:
    int value;
    std::string name;

public:
    Derived(int v = 0, const std::string& n = "") : value(v), name(n) {}

    // 实现克隆方法
    Base* clone() const override {
        return new Derived(*this);
    }

    void display() const override {
        std::cout << "Value: " << value << ", Name: " << name << std::endl;
    }
};


int main() {
    Derived obj1(42, "Derived Object");
    std::cout << "Original object: ";
    obj1.display();

    // 使用 clone 方法进行克隆
    Base* obj2 = obj1.clone();
    std::cout << "Cloned object: ";
    obj2->display();

    delete obj2;

    return 0;
}

使用模板和完美转发:使用模板函数进行克隆,通过完美转发将参数传递给对象的构造函数,实现通用的克隆机制。

完美转发:在 C++ 中,完美转发(Perfect Forwarding)是一种将参数以其原始的类型和值类别(左值或右值)传递给另一个函数的技术。它主要使用 std::forward 函数模板和转发引用(也称为万能引用,Forwarding Reference)来实现。

#include <iostream>
#include <utility>

template <typename T, typename... Args>
T* clone(Args&&... args) {
    return new T(std::forward<Args>(args)...);
}


class SimpleClass {
private:
    int value;

public:
    SimpleClass(int v = 0) : value(v) {}

    void display() const {
        std::cout << "Value: " << value << std::endl;
    }
};


int main() {
    SimpleClass obj1(10);
    std::cout << "Original object: ";
    obj1.display();

    // 使用模板函数进行克隆
    SimpleClass* obj2 = clone<SimpleClass>(obj1);
    std::cout << "Cloned object: ";
    obj2->display();

    delete obj2;

    return 0;
}

如何实现单例模式?

懒汉式(线程不安全)

#include <iostream>


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

public:
    static Singleton* getInstance() {
        if (instance == nullptr) {
            instance = new Singleton();
        }
        return instance;
    }


    void display() const {
        std::cout << "This is a singleton instance." << std::endl;
    }
};


Singleton* Singleton::instance = nullptr;


int main() {
    Singleton* s1 = Singleton::getInstance();
    Singleton* s2 = Singleton::getInstance();
    s1->display();
    s2->display();
    // 注意:没有释放内存,可能导致内存泄漏
    return 0;
}

 懒汉式(线程安全,使用互斥锁)

#include <iostream>
#include <mutex>


class Singleton {
private:
    static Singleton* instance;
    static std::mutex mtx;
    Singleton() {}  // 构造函数私有,防止外部实例化

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


    void display() const {
        std::cout << "This is a singleton instance." << std::endl;
    }
};


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


int main() {
    Singleton* s1 = Singleton::getInstance();
    Singleton* s2 = Singleton::getInstance();
    s1->display();
    s2->display();
    // 注意:没有释放内存,可能导致内存泄漏
    return 0;
}

 饿汉式

#include <iostream>


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

public:
    static Singleton* getInstance() {
        return instance;
    }


    void display() const {
        std::cout << "This is a singleton instance." << std::endl;
    }
};


Singleton* Singleton::instance = new Singleton();


int main() {
    Singleton* s1 = Singleton::getInstance();
    Singleton* s2 = Singleton::getInstance();
    s1->display();
    s2->display();
    // 注意:没有释放内存,可能导致内存泄漏
    return 0;
}

Meyers' Singleton (C++11 及以后)

#include <iostream>


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


public:
    static Singleton& getInstance() {
        static Singleton instance;
        return instance;
    }


    void display() const {
        std::cout << "This is a singleton instance." << std::endl;
    }
};


int main() {
    Singleton& s1 = Singleton::getInstance();
    Singleton& s2 = Singleton::getInstance();
    s1.display();
    s2.display();
    return 0;
}