C++知识点总结
回调函数:
程序通过参数把该函数指针传递给其他函数,在那个函数中调用这个函数指针就相当于调用这个函数,这个过程就叫回调,而被调用的函数就叫回调函数。回调函数的本质就是函数指针传递。
函数指针和指针函数的区分(后面是本质):
函数指针:指向一个函数的指针,如int (*fun)(int x,int y),调用时可以用 * 取具体值的方式来调用函数;
指针函数:返回值是一个指针,但其本质还是一个函数,如void f(int a,int b)。
C++可以使用全局函数和静态函数作为回调函数。考虑到全局函数会破坏封装性,所以一般都用静态成员函数。
C++手写单例模式
#include <bits/stdc++.h>
#define ll long long
#define mem( f, x ) memset( f, x, sizeof(f))
#define pii pair<int,int>
#define fi first
#define se second
#define mk(x,y) make_pair(x,y)
#define pk push_back
using namespace std;
const int M = 1e6+5;
const int N = 1e6+5;
const int MOD = 1e9+7;
const ll INF = 2e10;
/*
class node{
public:
node(){ cout << "node()" << endl; }
static int get(){
return a;
}
private:
static int a;
};
// 静态成员变量的初始化放在类外
int node::a=1;
int main( ){
node p;
cout << node::get() << endl;
return 0;
}
*/
// 饿汉模式
class Hunger_Singleon{
private:
static Hunger_Singleon* instance;
public:
Hunger_Singleon(){ cout << "Hunger_Singleon\n"; }
static Hunger_Singleon* getSingleon(){
return instance;
}
static void destroy(){
delete instance;
instance = NULL;
}
~Hunger_Singleon(){
if( instance != NULL )
delete instance;
instance = NULL;
}
};
// 懒汉模式
class Lazy_Singleon{
private:
static Lazy_Singleon* instance;
public:
Lazy_Singleon(){ cout << "Lazy_Singleon\n"; }
static Lazy_Singleon* getSingleon(){
if( !instance )
instance = new Lazy_Singleon();
return instance;
}
static void destroy(){
if( instance != NULL )
delete instance;
instance = NULL;
}
~Lazy_Singleon(){
if( instance != NULL )
delete instance;
instance = NULL;
}
};
Hunger_Singleon* Hunger_Singleon::instance = new Hunger_Singleon();
Lazy_Singleon* Lazy_Singleon::instance = NULL;
int main( ){
Hunger_Singleon* s1 = Hunger_Singleon::getSingleon();
Hunger_Singleon* s2 = Hunger_Singleon::getSingleon();
Hunger_Singleon* s3 = Hunger_Singleon::getSingleon();
Lazy_Singleon* l1 = Lazy_Singleon::getSingleon();
Lazy_Singleon* l2 = Lazy_Singleon::getSingleon();
Lazy_Singleon* l3 = Lazy_Singleon::getSingleon();
cout << s1 << "\n" << s2 << "\n" << s3 << "\n";
cout << l1 << "\n" << l2 << "\n" << l3 << "\n";
return 0;
}
注: 静态成员函数只能访问静态成员变量,而不能访问非静态成员变量。
JAVA手写单例对比:
// HungerSingleon饿汉模式
package com.xxxx.seckill;
public class HungerSingleon {
private int val;
private String id;
HungerSingleon() {
val = 0;
id = "HungerSingleon";
}
HungerSingleon(int val, String id) {
this.val = val;
this.id = id;
}
// 饿汉一开始就对单例进行初始化操作
private static HungerSingleon instance = new HungerSingleon();
public static HungerSingleon getInstance() {
return instance;
}
@Override
public String toString() {
return "HungerSingleon [id=" + id + ", val=" + val + "]";
}
}
// LazySingleon懒汉模式
package com.xxxx.seckill;
public class LazySingleon {
private int val;
private String id;
// volatile保证访问instance的有序性和可见性
private volatile static LazySingleon instance = null;
LazySingleon() {
val = 0;
id = "LazySingleon";
}
public LazySingleon(int val, String id) {
this.val = val;
this.id = id;
}
static public LazySingleon GetInstance() {
if (instance == null) {
// 只对instance初始化过程进行synchronized加锁,不对检查过程进行加锁,可提高运行效率
synchronized (LazySingleon.class) {
// 懒汉访问时才对单例进行初始化
instance = new LazySingleon();
}
}
return instance;
}
@Override
public String toString() {
return "LazySingleon [id=" + id + ", val=" + val + "]";
}
}
// 测试函数
package com.xxxx.seckill;
public class Starter {
public static void main(String[] args) {
System.out.println(HungerSingleon.getInstance());
System.out.println(LazySingleon.GetInstance());
}
}