Boost库-实用工具

1.compressed_pair

#include<boost/compressed_pair.hpp>

作用:使用模板元编程技术和多重继承来优化空类成员,可以“压缩”pair大小来节约空间。

使用如下,分析:

(1)空类是指没有非静态成员变量(会增加类实例大小),没有虚函数(会导致虚表指针)。

(2)仿照make_pair()实现make_compressed_pair()。

(3)输出4是空类被优化掉了,输出8是空类因字节对齐等于4,输出1是其中一个空类被优化掉了。

#include<iostream>
#include<boost/compressed_pair.hpp>
using namespace std;

class emptyClass
{
public:
	void show() { cout << "empty class" << endl;; }
};


template<typename T1, typename T2>
boost::compressed_pair<T1, T2>
make_compressed_pair(T1 t1, T2 t2)
{
	return boost::compressed_pair<T1, T2>(t1, t2);
}

int main()
{
	auto pair1=make_compressed_pair(42, emptyClass());
	pair1.second().show();   //输出empty class

	cout << sizeof(boost::compressed_pair<int,emptyClass>) << endl;  //输出4 
	cout << sizeof(pair<int, emptyClass>) << endl;  //输出8
	cout << sizeof(boost::compressed_pair<emptyClass, emptyClass>) << endl;  //输出1
	cout << sizeof(pair<emptyClass, emptyClass >) << endl;  //输出2

	return 0;
}

2. checked_delete/checked_array_delete

#include<boost/checked_delete.hpp>

作用:可以在编译器保证delete/delete[]删除的是一个指向”完整类型“的指针,避免运行期发生未定义行为,是更加智能的delete/delete[]。

使用1如下,分析:删除函数前只有类声明,所以调用do_delete()时,没有调用析构函数,将导致资源未释放等未定义行为,可能会警告【删除指向不完整“demo”类型的指针;没有调用析构函数】;而使用checked_delete()既方便又避免了这种写法错误。

 使用2如下,分析:

(1)只声明而没有具体定义,使用delete p时,可能会警告;而使用checked_delete()时,代码无法编译,会报错【static_assert failed: 'Type must be complete'  】和【使用了未定义类型“demo” 】。

(2)【注意】checked_delete()删除指针后并不会将其设置为nullptr。

 

 使用建议:因某些原因不能使用智能指针,必须手工管理内存,那就使用checked_delete/check_array_delete,它可以保证在编译期就发现隐藏错误。

3.addressof

#include<boost/utility/addressof.hpp>或#include<memory>

作用:若重载了operator&的类,直接使用&会失效(实际上调用了重载的operator&)但addressof()总能获得操作对象的真实地址。

使用如下,分析:使用&p获得的是p.y地址,main函数结束时,会因为下溢而中断【Run-Time Check Failure #2 - Stack around the variable 'p' was corrupted] 。

 使用建议:怀疑某个类可能重载了operator&,那就使用addressof获取对象真正地址。

4.base_from_member 

#include<boost/utility/base_from_member.hpp>

作用:有时基类需要由派生类的成员变量来初始化,但基类必须在派生类之前完成初始化,而那时的派生类的成员是未定义的。解决:1、把派生类的成员移动到另一个辅助基类中。2、base_from_member 使用多重继承和模板技术提供了用成员初始化基类的惯用法。base_from_member 默认有11个构造函数,最大支持10个参数;也可以定义宏#define BOOST_BASE_FROM_MEMBER_MAX_ARITY 2 (3个构造函数,最大支持2个参数)。

使用如下,分析:base没有被正确初始化。

 解决1,把派生类的成员移动到另一个辅助基类中。

#include<iostream>
#include<complex>
#include<boost/utility/base_from_member.hpp>
using namespace std;

class base
{
public:
	base(complex<int>c) { cout << "base:" << c << endl; }
};

class pbase  //手工编写的辅助类
{
protected:
	complex<int>c;   //成员变量都移动到这个辅助类
	pbase(int a,int b):c(a,b){}   
};

class derived :private pbase,public base
{
public:
	derived(int a, int b) :pbase(a, b), base(c) { cout << "derived:" << c << endl; }
};

int main()
{
	derived d(1, 2);
	return 0;
}

解决2,使用base_from_member。【注意】成员变量的名字是member。

#include<iostream>
#include<complex>
#include<boost/utility/base_from_member.hpp>
using namespace std;

class base
{
public:
	base(complex<int>c) { cout << "base:" << c << endl; }
};


class derived :private boost::base_from_member<complex<int>>,public base
{
	using pbase = boost::base_from_member<complex<int>>; //简化
public:
	derived(int a, int b) :pbase(a, b), base(member) { cout << "derived:" << member << endl; } 
};

int main()
{
	derived d(1, 2);
	return 0;
}

5.conversion

隐式类型转换由编译器自动完成:char,short->int->unsigned->long->double, float->double。

显式类型转换由程序员手工强制完成:

(1)使用()。

(2)标准转型操作符,能够避免许多任意转型引起的潜在错误。

        const_cast:用于增加或删除const、volatile修饰。

        static_cast:可以显式执行隐式类型转换。

        reinterpret_cast:对目标的内存二进制位进行低层次的重新解释。

        dynamic_cast:用于多态对象(即存在虚函数的对象)间类型转换,将基类指针或引用转换为派生类指针或引用,从而访问派生类特有的成员。【注意】引用转型失败会抛异常”bad_cast“;指针转型失败会返回一个空指针(nullptr),如果漏写检查代码(assert/if语句)会导致安全隐患,使用boost::polymorphic_downcast/boost::polymorphic_cast会更安全地进行多态对象间转型。

(3)boost::lexical_cast,用于基本数据类型和字符串之间的转换,使用如下。

         #include<boost/lexical_cast.hpp>

         【注意】boost::trim,用于去除字符串首尾的空白字符(空格、制表符、换行符等)。

         #include<boost/algorithm/string.hpp>

#include<iostream>
#include<boost/lexical_cast.hpp>
#include<boost/algorithm/string.hpp>
using namespace std;


int main()
{
	string str = " 12.3 ";
	boost::trim(str);
	double a = boost::lexical_cast<double>(str);
	cout << a << endl;

	return 0;
}


polymorphic_downcast:引用/指针转型。对指针安全操作:断言转型成功。

polymorphic_cast:指针转型。对指针安全操作:空指针检查,若空指针抛异常”bad_cast“。

#include<boost/polymorphic_cast.hpp>

#include<iostream>
#include<boost/polymorphic_cast.hpp>
using namespace std;

class base {
public:
    virtual ~base() {}
};


class derived : public base {
public:
    void derivedFunction() {
        cout << "derived function" << endl;
    }
};

int main()
{
    base* b = new derived;

    derived* d = boost::polymorphic_cast<derived*>(b);
    d->derivedFunction();

    derived& d2 = boost::polymorphic_downcast<derived&>(*b); //转引用只能用polymorphic_downcast
    d2.derivedFunction();

    delete b;

	return 0;
}

6.numeric_cast

#include<boost/numeric/conversion/cast.hpp>

作用:在数字转型时进行范围检查,如果超出范围就抛异常"bad_cast",相比static_cast更安全,避免潜在错误。

使用如下:分析:使用static_cast不异常,使用numeric_cast超出范围,上溢异常。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值