条款六大概

代理类:   MyarraySize就是代理类

所谓代理类就是以模仿和增强一些类型的行为为目的而存在的类。

MyarraySize 就是仿照int 的代理类 增强行为

在vector<bool>中 

std::vector<bool> features(const Widget& w);
Widget w;
bool highPriority = features(w)[5];     //w高优先级吗?
processWidget(w, highPriority);         //根据它的优先级处理w

auto highPriority = features(w)[5];     //w高优先级吗?
processWidget(w,highPriority);          //未定义行为!

使用autohighPriority不再是bool类型。虽然从概念上来说std::vector<bool>意味着存放bool,但是std::vector<bool>operator[]不会返回容器中元素的引用(这就是std::vector::operator[]可返回除了bool以外的任何类型),取而代之它返回一个std::vector<bool>::reference的对象(一个嵌套于std::vector<bool>中的类)。

std::vector<bool>::reference之所以存在是因为std::vector<bool>规定了使用一个打包形式(packed form)表示它的bool,每个bool占一个bit。那给std::vectoroperator[]带来了问题,因为std::vector<T>operator[]应当返回一个T&,但是C++禁止对bits的引用。无法返回一个bool&std::vector<bool>operator[]返回一个行为类似于bool&的对象。要想成功扮演这个角色,bool&适用的上下文std::vector<bool>::reference也必须一样能适用。
 

bool highPriority = features(w)[5];     //显式的声明highPriority的类型
 

这里,features返回一个std::vector<bool>对象后再调用operator[]operator[]将会返回一个std::vector<bool>::reference对象,然后再通过隐式转换赋值给bool变量highPriorityhighPriority因此表示的是features返回的std::vector<bool>中的第五个bit,这也正如我们所期待的那样。

auto highPriority = features(w)[5];     //推导highPriority的类型

同样的,features返回一个std::vector<bool>对象,再调用operator[]operator[]将会返回一个std::vector<bool>::reference对象,但是现在这里有一点变化了,auto推导highPriority的类型为std::vector<bool>::reference,但是highPriority对象没有第五bit的值。

这个值取决于std::vector<bool>::reference的具体实现。其中的一种实现是这样的(std::vector<bool>::reference)对象包含一个指向机器字(word)的指针,然后加上方括号中的偏移实现被引用bit这样的行为。然后再来考虑highPriority初始化表达的意思,注意这里假设std::vector<bool>::reference就是刚提到的实现方式。

调用features将返回一个std::vector<bool>临时对象,这个对象没有名字,为了方便我们的讨论,我这里叫他tempoperator[]temp上调用,它返回的std::vector<bool>::reference包含一个指向存着这些bits的一个数据结构中的一个word的指针(temp管理这些bits),还有相应于第5个bit的偏移。highPriority是这个std::vector<bool>::reference的拷贝,所以highPriority也包含一个指针,指向temp中的这个word,加上相应于第5个bit的偏移。在这个语句结束的时候temp将会被销毁,因为它是一个临时变量。因此highPriority包含一个悬置的(dangling)指针,如果用于processWidget调用中将会造成未定义行为:

class Myarray
{
public:
    // 定义MyarraySize类,用于实现数组大小
    class MyarraySize
    {
    public:
        // 构造函数,用于初始化数组大小
        MyarraySize(int size) : thesize(size) {}
        // 返回数组大小
        int size() const { return thesize; }
        // 返回数组大小,用于比较
        operator int() const { return thesize; }

    private:
        int thesize;
    };

    // 构造函数,用于初始化数组大小
    Myarray(MyarraySize size) : size_(size), data_(new int[size_])
    {
    }
    // 重载索引操作符,用于返回数组元素
    int operator[](int index)
    {
        return data_[index];
    }
    // 重载比较操作符,用于比较两个数组是否相等
    bool operator==(const Myarray &temp)
    {
        return data_ == temp.data_;
    }
    // 返回数组大小
    MyarraySize size() { return size_; }
    // 销毁数组
    ~Myarray()
    {
        if (data_)
        {
            delete data_;
        }
    }

private:
    // 定义数组指针
    int *data_;
    // 定义数组大小
    MyarraySize size_;
};
class Myarray_
{
public:
    explicit Myarray_(int size) : size_(size), data_(new int[size])
    {
        cout << "1231311" << endl;
    }
    Myarray_(std::string a)
    {
    }
    ~Myarray_()
    {
        if (data_)
        {
            delete data_;
        }
    }

private:
    int *data_;
    int size_;
};



不能用引用去接临时类型的引用 (空间被释放会指向被释放的区域)

  

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值