0%

11.21碎片问题补充C++相关计算机基础相关

11.21碎片问题

11.21碎片问题

 

使用C++创建单例模式

之前用多了C#轮椅以为自己就是单例模式懂哥了,结果却抛弃了C++原有的底层知识

#include <iostream>

class Singleton {
public:
// 获取单例实例的静态方法
static Singleton& getInstance() {
// 使用局部静态变量确保线程安全的初始化
static Singleton instance;
return instance;
}

// 删除拷贝构造函数和赋值运算符重载,确保单例不会被复制
Singleton(const Singleton&amp;) = delete;
void operator=(const Singleton&amp;) = delete;

void doSomething() {
    std::cout &lt;&lt; &quot;Singleton is doing something.&quot; &lt;&lt; std::endl;
}

private:
// 私有构造函数,确保外部无法直接实例化
Singleton() {
// 进行初始化工作
}
};

int main() {
// 获取单例实例
Singleton& singleton = Singleton::getInstance();
// 使用单例实例
singleton.doSomething();

return 0;

}

 

delete this

什么情况下要用到呢

  1. 对象自毁:在对象的成员函数中,如果确定对象在某个条件下需要自毁,可以使用 delete this。但是需要确保在 delete this 之后不再访问对象的任何成员。
  2. 对象池:在一些特殊的对象池设计中,当对象不再需要时,可以通过调用自身的成员函数来删除自己。
  3. 异步操作:在一些异步操作中,可能需要在回调函数中删除对象自身。

 

operator newplacement new

operator new就是常见的new用法,在堆上分配内存空间并利用对象的构造函数来创建对象,如:

MyClass* obj = new MyClass;

placement new是一个特殊的new,区别时在已经有的空间上创建对象,如

MyClass* obj = new(ptr) MyClass;

就是在ptr指定的内存段上创建对象,不会分配新的内存空间

 

static关键字的全面解析,extern关键字的全面解析

 

static

对于C、C++、C#中的static的含义其实是大部分一致的,不同的地方取决与语言自身功能性的不同,比如纯C语言不带有的成员函数,那么static在这一方面就不存在意义。

局部变量

普通的局部变量生命周期和其作用域一致,但加上static关键字后该局部变量由栈内存转移到静态存储区,在整个程序的生命周期中都存在,但是对于其他函数来说是不可见的。

全局变量

定义在函数体外部的全局变量整个工程都可见,其他文件使用extern后可直接使用。所以说两个文件不能定义同名的全局变量,除非使用static。

增加static后,该全局变量的作用域就会限制在该文件之内。

函数

在同一个工程中的不同文件中的函数可以直接相互调用,因为在链接的时候会被统一编译链接。对于static则和全局变量一样,使用static的函数只能在定义其的文件中可见。

数据成员

静态数据成员不隶属于任何对象,所有的对象都拥有同一份静态成员,在没用类对象的时候也可以进行操作,也遵顼public等访问规则。

在访问静态数据成员时,访问方式如:

obj.a=1或者MyClass::a=1

obj为对象,MyClass为类类型

相对于全局变量来说,静态成员不存在于其他全局名字冲突的可能性(显然类名已经做了区分);同时,静态成员变量可以用private隐藏,而全局变量不能。

成员函数

静态成员函数同样不隶属于对象而是隶属于类,其特性是没有this指针(想想就明白了)

C#中的新static

C#中类也可以static,但是静态类的所有成员都必须也是静态的。

 

extern

如上,如果两个文件(同一工程)想互通全局变量,那么访问文件的使用全局变量需要加上extern关键字。

有一个推荐的方法是文件A正常定义全局变量,然后在文件A中的h文件里加上extern该全局变量的声明,于是其他文件想使用就直接include就可以了——要知道include就是将代码“备份”进去。

extern “C”

它告诉编译器C++按照C方法进行函数名的处理,主要是因为C++支持函数重载而C不支持。

例如C++中

void A(int a);

void A(int a,int b);

这两个函数名相同,但在C++编译器中编译后函数名其实会变化,用来区分两个参数列表不同的重载函数。但C语言中没有这个机制,也就是说在处理这方面两种编译器的措施是不同的,所以在C++中使用C文件函数时要用extern{}来声明:

extern{void A(int a);}

假如A没有重载

确保链接的时候不会发生错误。

 

纯C语言实现面向对象

纯C函数没有类说法,也没有对象说法,但其实也可以通过一些手段来模拟实现。

  • 结构体-->模拟类。
  • 函数指针-->在结构体中声明函数指针模拟类方法。
  • 封装-->前两者实现封装,也就是数据和相关操作绑定在一起。
  • 继承-->结构体中包含指向父类结构体的指针。
  • 多态-->函数指针动态绑定来实现(在使用时变化函数指针的指向)。

看起来太笨拙了不是吗?但你就说是不是面向对象嘛