C++ 学习

本文深入探讨C++中的函数后置const、四大函数(构造函数、拷贝构造、拷贝赋值)、设计模式中的单例模式以及内存管理的堆栈和智能指针。详细讲解了构造函数的初始化列表、深拷贝的重要性、单例模式的实现方式,以及堆栈内存分配的细节。同时,文章也触及了STL中的list和deque容器的内部工作原理。
摘要由CSDN通过智能技术生成

待整理

函数的后置const

在这里插入图片描述

class TestNode {
   
public:
    string member="B";

    string get_member() const{
   
        return this->member;
    }
};

int main() {
   
    const TestNode node;
    cout << node.get_member() << endl;
}

四大函数

构造函数

C++ 类构造函数初始化列表

类构造函数初始化列表:

使用初始化列表是显式地初始化,否则为赋值

有的时候必须用带有初始化列表的构造函数:

  1. 成员类型是没有默认构造函数的类。若没有提供显示初始化式,则编译器隐式使用成员类型的默认构造函数,若类没有默认构造函数,则编译器尝试使用默认构造函数将会失败
  2. const 成员引用类型的成员。因为 const 对象或引用类型只能初始化,不能对他们赋值。
class NoDefaultConstructor {
   
public:
    int data;

    NoDefaultConstructor(int data) : data(data) {
   }
};

class ListInitializing {
   
public:
    NoDefaultConstructor noDefaultConstructor;
    string &str;

    ListInitializing(string str) : noDefaultConstructor(0), str(str) {
   }
};

int main() {
   
    string str="1,2,3";
    ListInitializing listInitializing(str);
    ListInitializing listInitializing2("123");
//    string &str="123";
    string pre="123";
    string &str1=string("pre");

在这里插入图片描述

拷贝构造 + 拷贝赋值

拷贝构造拷贝赋值 的出发条件

在这里插入图片描述如果没写,编译器会自动实现一套

如果类里面的成员变量有指针,默认的 拷贝构造 会表现出浅拷贝

只要类带着指针,一定要写出这两种函数:

  • copy constructor
  • copy assignment operator

在这里插入图片描述

String(const String& str);
String& operator=(conat String& str);

在这里插入图片描述
default copy会造成【浅拷贝】和【内存泄露】的问题

深拷贝:

兄弟之间互为friend

在这里插入图片描述
在这里插入图片描述

其他

在这里插入图片描述

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

当前类的其他对象的pivate成员,对于当前类是可见的

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述s1, s2 在栈空间,p在堆空间,离开scope后p不会释放,并且无法被访问

内存泄露?

在这里插入图片描述

不检测自我赋值,可能会凉

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
new做的3个动作:

  1. 调用malloc(void* 指针)
  2. 转型
  3. 调用构造函数

在这里插入图片描述

在这里插入图片描述
pass by reference 不加 const 时,遇到临时变量,不能编译通过

在这里插入图片描述

在这里插入图片描述
In general, any time you need to write your own custom copy constructor, you also need to write a custom assignment operator.

在这里插入图片描述48,写31,如果还给操作系统,写30

在这里插入图片描述

在这里插入图片描述没有人调用getInstance的话,static A a不会存在,首次调用后存在于全局空间。
在这里插入图片描述

  • composition

has-a

组合,适配器模式,

deque可以念diQ或带克
在这里插入图片描述

  • delegation

composition by reference

  • inherence

is-a

在这里插入图片描述
函数的继承不应该从内存的角度去理解,而应该从调用权的角度去理解

在这里插入图片描述

设计模式

单例模式

博客园 - C++ 单例模式总结与剖析

  • 双检锁 + 智能指针
#include <memory>
#include <mutex>
#include <cstdio>

class Singleton {
   
public:
    typedef std::shared_ptr<Singleton> Ptr;

    ~Singleton() {
   
        printf("destructor\n");
    }

    Singleton(const Singleton &) = delete;

    Singleton &operator=(const Singleton &) = delete;

    static Ptr get_instance() {
   
        if (instance_ptr == nullptr) {
   
            std::lock_guard<std::mutex> lk(m_mutex);
            if (instance_ptr == nullptr) {
   
                instance_ptr = Ptr(new Singleton);
            }
        }
        return instance_ptr;
    }

private:
    Singleton() {
   
        printf("constructor\n");
    }

    static Ptr instance_ptr;
    static std::mutex m_mutex;
};

Singleton::Ptr Singleton::instance_ptr = nullptr;
std::mutex Singleton::m_mutex;

int main() {
   
    Singleton::Ptr p = Singleton::get_instance();
}

在这里插入图片描述

在这里插入图片描述

  • 局部静态变量
#include <cstdio>

class Singleton {
   
public:

    ~Singleton() {
   
        printf("destructor\n");
    }

    Singleton(const Singleton &) = delete;

    Singleton &operator=(const Singleton &) = delete;

    static Singleton &get_instance() {
   
        static Singleton instance;
        return instance;
    }

private:
    Singleton() {
   
        printf("constructor\n");
    }
};


int main() {
   
    Singleton &instance1 = Singleton::get_instance();
    Singleton &instance2 = Singleton::get_instance();
    Singleton &instance3 = Singleton::get_instance();
    return 0;
}

所用到的特性是在C++11标准中的Magic Static特性:

If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.
如果当变量在初始化的时候,并发同时进入声明语句,并发线程将会阻塞等待初始化结束。

这样保证了并发线程在获取静态局部变量的时候一定是初始化过的,所以具有线程安全性。

C++静态变量的生存期 是从声明到程序结束,这也是一种懒汉式

内存管理

堆栈

scope object == auto object ==

global object可以视为static object

在这里插入图片描述

new被分解为3个动作

内存分配的cookie

两个cookie各4B,分配的内存必须以16B为单位进行分配,否则会填充

在这里插入图片描述
因为cookie+以16B为单位进行内存分配的原因,

对于double , long long这样的8B,16B相当于2个
对于int, float这样的4B,16B相当于4个,其他以此类推

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

allocator

  • defalloc.h

// Inclusion of this file is DEPRECATED. This is the original HP
// default allocator. It is provided only for backward compatibility.
// This file WILL BE REMOVED in a future release.
//
// DO NOT USE THIS FILE unless you have an old container implementation
// that requires an allocator with the HP-style interface.
//
// Standard-conforming allocators have a very different interface. The
// standard default allocator is declared in the header .

#ifndef DEFALLOC_H
#define DEFALLOC_H

#include <new.h>
#include <stddef.h>
#include <stdlib.h>
#include <limits.h>
#include <iostream.h>
#include <algobase.h>


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值