C++ 脑图(二)类型转换、单例、多态、模板、智能指针

目录

1、类型转换、特殊类、单例模式

1)类型转换

2)、特殊类:

只能堆上建对象

只能栈上建对象

 3、单例模式

1. 懒汉式单例(线程不安全)

2. 懒汉式单例(线程安全) 

 3. 饿汉式单例

4、使用std::call_once 实现单例

2、多态原理

 编译时多态

3、模板:

​编辑函数模板与特化

类模板与特化

 4、智能指针

unique_ptr

 shared_ptr- weak_ptr

循环引用


1、类型转换、特殊类、单例模式

1)类型转换

#include <iostream>
class Base
{
public:
    virtual void show() { std::cout << "Base class" << std::endl; }
};

class Derived : public Base
{
public:
    void show() override { std::cout << "Derived class" << std::endl; }
};
void printValue(const int *value)
{
    std::cout << "Value: " << *value << std::endl;
}
int main()
{
    int intValue = 10;
    double doubleValue = intValue;                         // 隐式转换,编译器自动进行的转换
    std::cout << "隐式转换: " << doubleValue << std::endl; // 输出 10.0
    double dValue = 10.5;
    int intV = (int)dValue;                           // C 风格转换 type强转
    std::cout << "C 风格转换: " << intV << std::endl; // 输出 10
    Base *basePtr = new Derived();
    Derived *derivedPtr = static_cast<Derived *>(basePtr); // 使用 static_cast
    derivedPtr->show();                                    // 输出 "Derived class"
    delete basePtr;

    Base *basePtr1 = new Derived();
    Derived *derivedPtr1 = dynamic_cast<Derived *>(basePtr1);
    // 使用 dynamic_cast用于多态类型转换,确保安全性

    if (derivedPtr1)
    {
        derivedPtr1->show(); // 输出 "Derived class"
    }
    else
    {
        std::cout << "转换失败" << std::endl;
    }
    delete basePtr1;
    int num = 10;
    const int *constPtr = &num;
    printValue(constPtr); // 输出 10
    // 使用 const_cast 移除 const 属性
    int *modifiablePtr = const_cast<int *>(constPtr);
    *modifiablePtr = 20;  // 修改值
    printValue(constPtr); // 输出 20
    int num1 = 42;
    void *ptr = reinterpret_cast<void *>(&num1); // 使用 reinterpret_cast

    // 将 void* 转回 int*
    int *intPtr = reinterpret_cast<int *>(ptr);
    std::cout << "Value: " << *intPtr << std::endl; // 输出 42
    return 0;
}

2)、特殊类:

只能堆上建对象

#include <iostream>

class HeapOnly {
private:
    // 私有构造函数,防止栈上创建对象
    HeapOnly() {
        std::cout << "HeapOnly constructor called." << std::endl;
    }
public:
    // 静态成员函数,用于在堆上创建对象
    static HeapOnly* create() {
        return new HeapOnly();
    }
    // 示例成员函数
    void display() {
        std::cout << "This is a HeapOnly object." << std::endl;
    }
    // 禁止拷贝构造和赋值操作
    HeapOnly(const HeapOnly&) = delete;
    HeapOnly& operator=(const HeapOnly&) = delete;

    // 析构函数
    ~HeapOnly() {
        std::cout << "HeapOnly destructor called." << std::endl;
    }
};

int main() {
    // HeapOnly obj; // 编译错误:构造函数是私有的

    // 在堆上创建对象
    HeapOnly* heapObj = HeapOnly::create();
    heapObj->display();

    // 释放内存
    delete heapObj;
    return 0;
}

只能栈上建对象

#include <iostream>

class StackOnly {
public:
    // 公共构造函数
    StackOnly() {
        std::cout << "StackOnly constructor called." << std::endl;
    }
    ~StackOnly() {
        std::cout << "StackOnly destructor called." << std::endl;
    }
    // 示例成员函数
    void display() {
        std::cout << "This is a StackOnly object." << std::endl;
    }

private:
    // 私有析构函数,防止在堆上创建对象
    void* operator new(size_t) {};
    void operator delete(void*) {};
    // 禁止拷贝构造和赋值操作
    StackOnly(const StackOnly&) = delete;
    StackOnly& operator=(const StackOnly&) = delete;
};

int main() {
    // 在栈上创建对象
    StackOnly stackObj; // 合法
    stackObj.display();

    // StackOnly* heapObj = new StackOnly(); // 编译错误:析构函数是私有的

    return 0;
}

 3、单例模式

1. 懒汉式单例(线程不安全)

#include <iostream>

class Singleton {
private:
    static Singleton* instance;
    // 私有构造函数,防止外部实例化
    Singleton() {
        std::cout << "Singleton instance created." << std::endl;
    }

public:
    // 获取实例的静态方法
    static Singleton* getInstance() {
        if (instance == nullptr) {
            instance = new Singleton();
        }
        return instance;
    }
    //禁止拷贝和赋值
    Singleton(const Singleton&)=delete;
    Singleton operator=(const Singleton&)=delete;

    // 示例成员函数
    void showMessage() {
        std::cout << "Hello from Singleton!" << std::endl;
    }
};

// 静态成员初始化
Singleton* Singleton::instance = nullptr;
int main() {
    Singleton* singleton = Singleton::getInstance();
    singleton->showMessage();

    return 0;
}

2. 懒汉式单例(线程安全) 

#include <iostream>
#include <mutex>

class Singleton {
private:
    static Singleton* instance;
    static std::mutex mtx;

    // 私有构造函数
    Singleton() {
        std::cout << "Singleton instance created." << std::endl;
    }

public:
    // 获取实例的静态方法
    static Singleton* getInstance() {
        if (instance == nullptr) {
 //来确保在多线程环境中只有一个线程可以创建实例
            std::lock_guard<std::mutex> lock(mtx); // 加锁
            if (instance == nullptr) { //双重检查锁定
                instance = new Singleton();
            }
        }
        return instance;
    }
    //禁止拷贝和赋值
    Singleton(const Singleton&)=delete;
    Singleton operator=(const Singleton&)=delete;

    // 示例成员函数
    void showMessage() {
        std::cout << "Hello from Singleton!" << std::endl;
    }
};

// 静态成员初始化
Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mtx;

int main() {
    Singleton* singleton = Singleton::getInstance();
    singleton->showMessage();

    return 0;
}

 3. 饿汉式单例


#include <iostream>

class Singleton {
private:
    // 在类加载时就创建实例
    static Singleton instance;

    // 私有构造函数
    Singleton() {
        std::cout << "Singleton instance created." << std::endl;
    }
    //禁止拷贝和赋值
    Singleton(const Singleton&)=delete;
    Singleton operator=(const Singleton&)=delete;
public:
    // 获取实例的静态方法
    static Singleton& getInstance() {
        return instance; //静态方法 getInstance:返回已创建的实例
    }
    // 示例成员函数
    void showMessage() {
        std::cout << "Hello from Singleton!" << std::endl;
    }
};

// 静态成员初始化:instance 在类加载时就被创建
Singleton Singleton::instance; 

int main() {
    Singleton& singleton = Singleton::getInstance();
    singleton.showMessage();

    return 0;
}

4、使用std::call_once 实现单例

#include <iostream>
#include <mutex>

class Singleton {
public:
    // 获取单例实例的静态方法
    static Singleton& getInstance() {
        // 使用std::call_once保证initInstance只执行一次
        std::call_once(initFlag, &Singleton::initInstance);
        return *instance;
    }

    // 示例成员函数
    void doSomething() {
        std::cout << "Singleton instance doing something." << std::endl;
    }

private:
    Singleton() {
        std::cout << "Singleton constructor called." << std::endl;
    }
    ~Singleton() = default;

    // 禁止拷贝和赋值
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

    static void initInstance() {
        instance = new Singleton();
        // 如果需要,可以注册atexit清理instance
    }

    static Singleton* instance;
    static std::once_flag initFlag;
};

// 静态成员初始化
Singleton* Singleton::instance = nullptr;
std::once_flag Singleton::initFlag;

int main() {
    Singleton& s1 = Singleton::getInstance();
    s1.doSomething();

    Singleton& s2 = Singleton::getInstance();
    s2.doSomething();

    return 0;
}

2、多态原理

 编译时多态

函数重载运算符重载实现静态多态

#include <iostream>

class Complex {
private:
    double real;
    double imag;

public:
    Complex(double r, double i) : real(r), imag(i) {}

    // 运算符重载
    Complex operator+(const Complex& other) {
        return Complex(real + other.real, imag + other.imag);
    }
     void display(int a) {
        std::cout << "Integer: " << a << std::endl;
    }

    void display(double b) {
        std::cout << "Double: " << b << std::endl;
    }

    void display(const std::string& str) {
        std::cout << "String: " << str << std::endl;
    }
    void display() {
        std::cout << real << " + " << imag << "i" << std::endl;
    }
};

int main() {
    Complex c1(1.0, 2.0);
    Complex c2(3.0, 4.0);
    Complex c3 = c1 + c2; // 调用重载的 + 运算符
    c3.display(); // 输出: 4.0 + 6.0i
    c3.display(2); // 输出: Integer: 2
    c3.display(1.5); // 输出: Double: 1.5

    return 0;
}
#include <iostream>

class Base {
public:
    virtual void show() { // 虚函数
        std::cout << "Base class show function." << std::endl;
    }
    
    virtual ~Base() {std::cout << "Base destructor called." << std::endl;
    } // 虚析构函数
};

class Derived : public Base {
public:
    void show() override { // 重写虚函数
        std::cout << "Derived class show function." << std::endl;
    }
    ~Derived() {
        std::cout << "Derived destructor called." << std::endl;
    }
};

int main() {
    Base* b;           // 基类指针
    Derived d;        // 派生类对象
    b = &d;           // 指向派生类对象
    b->show();        // 调用派生类的 show(),输出: Derived class show function.
    return 0;
}

3、模板:

函数模板与特化

#include <iostream>
#include<string>

template <typename T>
T add(T a, T b) {
    return a + b;
}
// 特化版本:处理字符串
template <>
std::string add<std::string>(std::string a, std::string b) {
    return a + " - " + b; // 在字符串之间添加空格-
}
int main() {
    std::cout << add(5, 10) << std::endl;         // 调用 int 版本
    std::cout << add(3.5, 2.5) << std::endl;     // 调用 double 版本
    std::cout << add<std::string>("Hello, ", "World!") << std::endl; // 调用 string 版本
    return 0;
}

类模板与特化

#include <iostream>

template <typename T>
class Box {
private:
    T value;
public:
    Box(T v) : value(v) {}
    T getValue() const { return value; }
};
// 特化版本:处理 std::string
template <>
class Box<std::string> {
private:
    std::string value;
public:
    Box(std::string v) : value(v) {}
    std::string getValue() const { return "String value: " + value; }
};
int main() {
    Box<int> intBox(123);
    Box<double> doubleBox(45.67);
    Box<std::string> stringBox("Hello, Templates!");

    std::cout << intBox.getValue() << std::endl; // 输出: 123
    std::cout << doubleBox.getValue() << std::endl; // 输出: 45.67
    std::cout << stringBox.getValue() << std::endl; // 输出: String value: Hello, Templates!
    return 0;
}

 4、智能指针

unique_ptr

#include <iostream>
#include <memory>

class MyClass
{
public:
    MyClass() { std::cout << "MyClass constructed." << std::endl; }
    ~MyClass() { std::cout << "MyClass destructed." << std::endl; }
    void greet() { std::cout << "Hello, World!" << std::endl; }
};

int main()
{
    std::unique_ptr<MyClass> ptr1(new MyClass()); // 创建 unique_ptr
    ptr1->greet();                                // 使用 unique_ptr

    // std::unique_ptr<MyClass> ptr2 = ptr1; // 编译错误:不能拷贝
    std::unique_ptr<MyClass> ptr2 = std::move(ptr1); // 转移所有权
    // ptr1.reset(); // ptr1 现在为空

    if (!ptr1)
    {
        std::cout << "ptr1 is null." << std::endl;
    }

    ptr2->greet(); // 使用 ptr2
    // 自定义删除器:可以传递自定义删除器来管理资源的释放。
    std::unique_ptr<MyClass, void (*)(MyClass *)> ptr3(new MyClass(), [](MyClass *p)
                                                       {
    std::cout << "Custom deleter called." << std::endl;
    delete p; });
    return 0; // ptr2 超出作用域,自动释放内存
}

 shared_ptr- weak_ptr

#include <iostream>
#include <memory>

class MyClass {
public:
    MyClass() { std::cout << "MyClass constructed." << std::endl; }
    ~MyClass() { std::cout << "MyClass destructed." << std::endl; }
};

int main() {
    std::shared_ptr<MyClass> ptr1(new MyClass()); // 创建 shared_ptr
    {
        std::shared_ptr<MyClass> ptr2 = ptr1; // 共享所有权
        std::cout << "Reference count: " << ptr1.use_count() << std::endl; // 输出: 2
    } // ptr2 超出作用域,引用计数减一

    std::cout << "Reference count: " << ptr1.use_count() << std::endl; // 输出: 1
    std::weak_ptr<MyClass> weakPtr = ptr1; // 创建 weak_ptr
    std::cout << "Reference count: " << ptr1.use_count() << std::endl; // 输出: 1
    if (auto sharedPtr = weakPtr.lock()) { // 尝试获取 shared_ptr
        // 可以安全地使用 sharedPtr
        std::cout << "Weak pointer is valid." << std::endl;
    } else {
        std::cout << "Weak pointer is expired." << std::endl;
    }

    ptr1.reset(); // 释放资源

    if (auto sharedPtr = weakPtr.lock()) {
        std::cout << "Weak pointer is valid." << std::endl;
    } else {
        std::cout << "Weak pointer is expired." << std::endl; // 输出: Weak pointer is expired.
    }
    return 0; // ptr1 超出作用域,自动释放内存
}

循环引用

#include <iostream>
#include <memory>

class B; // 前向声明

class A {
public:
    std::shared_ptr<B> bPtr;
    ~A() { std::cout << "A destructed." << std::endl; }
};

class B {
public:
    std::shared_ptr<A> aPtr;
    //std::weak_ptr<A> aPtr;  //使用weak_ptr解决循环引用
    ~B() { std::cout << "B destructed." << std::endl; }
};

int main() {
    std::shared_ptr<A> a = std::make_shared<A>();
    std::shared_ptr<B> b = std::make_shared<B>();

    a->bPtr = b; // A 持有 B
    b->aPtr = a; // B 持有 A 如果是weak B 观察 A,但不拥有 A
    std::cout<<a.use_count()<<std::endl;

    return 0; // 此时 A 和 B 的引用计数都不为零,导致内存泄漏
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值