effective c++在资源管理类中提供对原始资源的访问

本文探讨了C++中资源管理类的设计,包括如何通过构造函数接收原生资源并进行管理,以及如何通过析构函数释放资源。同时,讨论了不同类型转换的方法,包括隐式转换和显式转换,并对比了它们的优缺点。此外,还介绍了函数对象的概念及其实现方式,以及shared_ptr和auto_ptr如何获取原生指针。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有关访问资源管理类中的原生指针

#include <iostream>
#include <cstdio>
using namespace std;
struct FontHandle{};
FontHandle getFont(){}
void releaseFont(FontHandle f){}
class Font//资源管理类
{
public:
    explicit Font(FontHandle fh):f(fh){}
    ~Font(){releaseFont(f);}
    FontHandle get()const{return f;}
    //显式的返回原生的资源
    operator FontHandle()const{return f;}
    //隐式的返回原生的资源
private:
    FontHandle f;
};
void changFontSize(FontHandle f){};
int main()
{
    Font f1(getFont());
    changFontSize(f1);//隐式的转化为Fonthandle格式
    changFontSize(f1.get());//显式的转化为Fonthandle格式
    FontHandle f2 = f1;
    //这里f2本来想定义为Font类型(coder不小心打成FontHandle)
    //f1隐式的转化为了底层资源FontHandle,然后才被复制的
    //当f1被销毁释放时,f2可能会成为空指针

    //隐式转换可能更易用
    //显式转换虽然麻烦,但是可以避免很多错误
    return 0;
}

在网上看了一些关于类型转换的文章,这里摘抄过来:
hkx1n的专栏

class Widget
{
public:
    Widget():a_(0) {}
    Widget(int a):a_(a) {}
    operator int& ()
    {
        return a_;
    }
private:
    int a_;
};
class Negate
{
public:
    int operator()(int n){ return -n;}
};
void Callback(int n, Negate & neg)
{
    int val = neg(n); //调用重载的操作符“()”
    //int val = neg.operator()(n);
    cout << val;
}
int main()
{
    Widget w(189);
    int a = w;
    cout << a << endl;
    Negate neg;
    Callback(5,neg);
    return 0;
}

C++,函数对象
尽管函数指针被广泛用于实现函数回调,但C++还提供了一个重要的实现回调函数的方法,那就是函数对象。函数对象(也称“算符”)是重载了“()”操作符的普通类对象。因此从语法上讲,函数对象与普通的函数行为类似。

用函数对象代替函数指针有几个优点,首先,因为对象可以在内部修改而不用改动外部接口,因此设计更灵活,更富有弹性。函数对象也具备有存储先前调用 结果的数据成员。在使用普通函数时需要将先前调用的结果存储在全程或者本地静态变量中,但是全程或者本地静态变量有某些我们不愿意看到的缺陷。

其次,在函数对象中编译器能实现内联调用,从而更进一步增强了性能。这在函数指针中几乎是不可能实现的。

重载操作语句中,记住第一个圆括弧总是空的,因为它代表重载的操作符名;第二个圆括弧是参数列表。一般在重载操作符时,参数数量是固定的,而重载“()”操作符时有所不同,它可以有任意多个参数。

shared_ptr和auto_ptr可以取出原生指针,并且都已经重载了operator->和operator*

#include <iostream>
#include <cstdio>
#include<memory>
using namespace std;
struct FontHandle
{
    void func()const{cout << "function" << endl;}
};
shared_ptr<FontHandle>sp(new FontHandle());
auto_ptr<FontHandle>ap(new FontHandle());
int main()
{
    FontHandle *p = sp.get();//获得FontHandle原生指针
    p -> func();
    p = ap.get();//获得FontHandle原生指针
    p -> func();
    sp -> func();
    ap -> func();
    (*sp).func();
    (*ap).func();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值