1、关于虚函数表的理解
#include<iostream>
using namespace std;
class Base1
{
public:
virtual void f(){ cout<<"Base1::f()"<<endl;}
virtual void g(){ cout<<"Base1::g()"<<endl;}
virtual void h(){ cout<<"Base1::h()"<<endl;}
private:
virtual void p(){ cout<<"Base1::p()"<<endl;}
};
class Base2
{
public:
virtual void f(){ cout<<"Base2::f()"<<endl;}
virtual void g(){ cout<<"Base2::g()"<<endl;}
virtual void h(){ cout<<"Base2::h()"<<endl;}
};
class Base3
{
public:
virtual void f(){ cout<<"Base3::f()"<<endl;}
virtual void g(){ cout<<"Base3::g()"<<endl;}
virtual void h(){ cout<<"Base3::h()"<<endl;}
};
class Derive:public Base1,public Base2,public Base3
{
public:
virtual void f(){ cout<<"Derive::f()"<<endl;}
virtual void f1(){ cout<<"Derive::f1()"<<endl;}
virtual void g1(){ cout<<"Derive::g1()"<<endl;}
virtual void h1(){ cout<<"Derive::h1()"<<endl;}
};
typedef void(*Fun)(void);
int main()
{
Derive d;
Fun pfun=NULL;
long** pvtab=(long**)&d;
//3x3
for(int i=0;i<3;i++)
{
for(int j=0;j<3;++j)
{
pfun=(Fun)pvtab[i][j];
pfun();
}
}
//1x3
pfun=(Fun)pvtab[0][3];
pfun();
pfun=(Fun)pvtab[0][4];
pfun();
pfun=(Fun)pvtab[0][5];
pfun();
//writing
pfun=(Fun)*((long*)*((long*)&d+2)+2);
pfun();
cout<<sizeof(Derive)<<endl;
cout<<sizeof(d)<<endl;
return 0;
}
2、C++实现单例模式
这篇非常全,就不复制粘贴了:
线程安全的单例模式C++实现_冬日笋丝的博客-CSDN博客_c++单例模式线程安全
C++如何实现单例模式?_Tattoo_Welkin的博客-CSDN博客_单例模式c++实现
饿汉模式:在类被加载时就被创建
#include<iostream>
//饿汉模式
using namespace std;
class A
{
public:
static A& GetInstance()
{
return a;
}
void set_data(int val)
{
data = val;
}
void print_data()
{
cout << data << endl;
}
private:
A() {};
~A() {};
//copy construct
A(const A& a);
A& operator=(const A& a);
//move cons
A(const A&& a);
A& operator=(const A&& a);
static A a;
int data;
};
A A::a;
int main()
{
A::GetInstance().set_data(100);
A::GetInstance().print_data();
return 0;
}
懒汉模式:类的单例实例在首次使用时就被创建(非线程安全)。(static离开函数依旧存在)
#include<iostream>
//懒汉模式
using namespace std;
class A
{
public:
static A* GetInstance()
{
static A a;
return &a;
}
void set_data(int val)
{
data = val;
}
void print_data()
{
cout << data << endl;
}
private:
A() {};
~A() {};
//copy construct
A(const A& a);
A& operator=(const A& a);
//move cons
A(const A&& a);
A& operator=(const A&& a);
int data;
};
int main()
{
A* a = A::GetInstance();
a->set_data(100);
a->print_data();
return 0;
}
懒汉模式:如果不采用静态局部对象,而改在堆上建立对象,则有两个问题需要解决,一个是内存泄漏的问题,一个是线程不安全的问题。
问题一:在析构函数析构。
问题二:双检测锁DCL来解决这个问题,保证创建对象的时候不被其他线程打扰。
C++11 的 lock_guard 和 unique_lock 的简单使用_gochenguowei的博客-CSDN博客_unique_lock和lock_guard
#include<iostream>
#include<mutex>
//懒汉模式,堆上建立对象
using namespace std;
mutex m_mutex;
class A
{
public:
static A* GetInstance()
{
if (!pA)
{
//生成一个lock_guard对象来管理mutex,生命周期结束自动解锁
lock_guard<mutex> lck(m_mutex);
if (!pA)
{
pA = new A();
}
}
return pA;
}
void set_data(int val)
{
data = val;
}
void print_data()
{
cout << data << endl;
}
private:
A() {};
~A() { delete pA; cout << "delete pA" << endl; };
//copy construct
A(const A& a);
A& operator=(const A& a);
//move cons
A(const A&& a);
A& operator=(const A&& a);
static A* pA;
int data;
};
A* A::pA = nullptr;
int main()
{
A* a = A::GetInstance();
a->set_data(100);
a->print_data();
return 0;
}
3、C++ try...catch语句用法
#include <iostream>
using namespace std;
double div(double x, double y)
{
if (y == 0)
{
throw(y);
}
return x / y;
}
int main()
{
try
{
double x = 20;
//double y = 5;
double y = 0;
cout << div(x, y) << endl;
}
catch (...)
{
cerr << "y is zero" << endl;
exit(1);
}
return 0;
}
4、用 C++设计一个不能被继承的类
【C++】设计一个不能被继承的类_小魏同学i的博客-CSDN博客
【C++】 设计一个不能被继承的类_Wan_shibugong的博客-CSDN博客
#include <iostream>
using namespace std;
//A:辅助类
template<class T>
class A
{
friend T;
private:
A()
{
cout << "A()" << endl;
}
~A()
{
cout << "~A()" << endl;
}
};
//B:所想要的不能被继承、但可以在堆、栈建立对象的类
class B:virtual public A<B>
{
public:
B()
{
cout << "B()" << endl;
}
~B()
{
cout << "~B()" << endl;
}
};
//C:无法构成对象
class C :public B
{
};
int main()
{
B b;
return 0;
}
5、判定是大端小端
网络大端
#include<iostream>
#include<cstdio>
#include<string>
union A
{
int i;
char c;
};
using namespace std;
int main()
{
A a;
a.i = 1;
if (a.c == 0)
{
cout << "大端" << endl;
}
else
{
cout << "小端" << endl;
}
return 0;
}