个人手撕代码三、C++特性相关

本文深入探讨了C++中的关键特性,包括虚函数表的工作原理,展示了如何通过虚函数表进行函数调用;详细介绍了C++的单例模式实现,包括线程安全的饿汉模式和懒汉模式;讲解了C++异常处理的try...catch语句用法,演示了如何捕获和处理运行时错误;此外,还展示了如何设计一个防止继承的类,以及如何判断系统是大端还是小端存储。
摘要由CSDN通过智能技术生成

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;
}

6、函数调用压栈

C/C++函数调用的压栈模型_zhangge3663的博客-CSDN博客_c++函数调用时压栈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值