数组订阅:返回Reference vs proxy类方法
Array Subscription: returning Reference vs proxy class method
在为模板类搜索重载Subscript('[]')运算符的方法时,我遇到了两种不同的技术。
第一种技术:
直接重载指向容器的operator []
返回指针,这将允许读取值和赋值。此技术的示例实现:
template <class T>
class X
{
int _size;
T *container;
public:
X(int sz)
{
_size=sz;
container=new T[sz]();
}
~X()
{
}
T& operator [](int indx)
{
return container[indx];
}
};
main()
为:
X<int> sample(100);
cout<<sample[9]<<endl;
sample[9]=9;
cout<<sample[9]<<endl;
输出:
0
9
第二种技术:
第二种技术涉及声明一个代理类并通过该类重载operator =
。此技术的示例实现:
template <class T>
class X
{
int _size;
T *container;
public:
X(int sz)
{
_size=sz;
container=new T[sz]();
}
~X()
{
}
class Proxy
{
int indx;
X<T> &parent;
public:
Proxy(X<T> &p, int x) : parent(p),indx(x)
{
}
void operator =(T assgn)
{
parent.container[indx]=assgn;
}
operator T const &()
{
return parent.container[indx];
}
friend class X<T>;//unnecessary line, I know!
};
Proxy operator[](int indx)
{
return Proxy(*this,indx);
}
};
使用相同的main()
,我们得到相同的输出。
我个人喜欢第二种方法。但是,我真的想比较一下这两种方法。这两种技术的主要功能区别是什么。每种方法都有什么优点?
如果您想要公开未按原样存储的元素序列(需要从存储转换为存储)或无法通过引用简单访问的元素序列,则可以使用您描述的基于代理的技术。一个例子是std::vector<bool>:它在存储中的每个字节中包含八个bool(每个位一个)。以这种方式存储它们时,不可能返回对单个此类布尔的引用,因此索引运算符返回一个"代理对象"来支持对所包含布尔的读写。
如果可以返回对存储对象的直接引用,那么将其封装在代理中并没有真正的优势,除非您想限制赋值(例如,只允许在容器中使用正值)。
通常,当您想要返回与数据的内部存储不匹配的内容时,会使用代理。经典的例子是2D矩阵,其中元素存储在单个数组中。如果提供了返回行或列的运算符,则需要代理。另一个例子是臭名昭著的std::vector<bool>
,其中数据不需要存储为bool
的块,但访问必须将bool
返回给用户。
代理可用于返回内部数据表示的段的不同"视图"。在您的示例中,似乎没有理由使用它们。
为大多数客户端使用正确的代理对象要困难得多。。。例如,如果有人说:
tcp_peer.send_from_iterator_range(&sample[2], &sample[7+1]);
如果sample::operator[]
返回一个临时代理,而该代理没有仔细替换operator&
,则代码会询问代理本身的地址。
在不失去代理拦截数据读取和/或写入的能力的情况下,无法支持某些客户端使用,例如在…中
Container::element_type& ref = container[n];
ref = 20;
客户端代码假定容器的CCD_ 10将产生对实际元素的引用。operator[]
返回的任何代理都必须提供operator element_type&()
(移交这样的引用并退出游戏),或者拒绝(例如,仅返回const
引用,返回非const
引用无法绑定的临时by值)并强制编辑客户端代码。
所以,当你需要代理时,代理的效果是95%,但当你不需要代理时最好避免。
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 如何为模板化对象创建模板向量?VS正在投掷C3203
- 数据成员SFINAE的C++17测试:gcc vs clang
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- 正在VS调试器中监视映射条目
- Confusion: decltype vs std::function
- 将IBM Rhapsody模型集成到VS 2019中
- VS Code "command":"make"与终端窗口中的命令行"make"不同
- 使用VS Code和CMake Tools运行自定义命令
- 修改 VS Code 中的默认C++代码段
- 如何使用c++在VS 2019上运行SQL查询
- vs 2015 constexpr变量不恒定,但与2019相比还好吗
- 完美前进使用 std::forward vs RefRefCast
- 从VS 2015更新3更新到VS2015更新3 d后浮点计算行为不同的原因
- VS 2015 链接错误 无法构建依赖于 libcurl 的项目
- consteval wrapper vs. source_location
- VS Code C++:不准确的系统包括路径错误(wchar.h,boost/lambda/lambda.hpp)
- QStringList vs list<shared_ptr<QString>> 性能比较C++
- 数组订阅:返回Reference vs proxy类方法