代理类: 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); //未定义行为!
使用
auto
后highPriority
不再是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::vector
的operator[]
带来了问题,因为std::vector<T>
的operator[]
应当返回一个T&
,但是C++禁止对bit
s的引用。无法返回一个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
变量highPriority
。highPriority
因此表示的是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>
临时对象,这个对象没有名字,为了方便我们的讨论,我这里叫他temp
。operator[]
在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_;
};
不能用引用去接临时类型的引用 (空间被释放会指向被释放的区域)