首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >数组订阅:返回引用与代理类方法

数组订阅:返回引用与代理类方法
EN

Stack Overflow用户
提问于 2014-04-10 06:27:30
回答 3查看 1.3K关注 0票数 3

在为模板类寻找重载Subscript('[]')操作符的方法时,我遇到了两种不同的技术。

第一种技术:

operator []返回指针直接重载到容器,这将允许读取值和赋值。此技术的示例实现如下:

代码语言:javascript
运行
复制
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()作为:

代码语言:javascript
运行
复制
X<int> sample(100);
cout<<sample[9]<<endl;
sample[9]=9;
cout<<sample[9]<<endl;

输出:

代码语言:javascript
运行
复制
0
9

第二种技术:

第二种技术涉及声明代理类并通过该类重载operator =。此技术的示例实现如下:

代码语言:javascript
运行
复制
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(),我们得到相同的输出。

我个人喜欢第二种方法。但是,我真的很想比较这两种方法。这两种技术的主要功能区别是什么?每种方法都有哪些优点?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-04-10 06:35:54

您描述的基于代理的技术可以使用,如果您想公开一个元素序列,这些元素不是这样存储的(需要从存储转换到存储),或者不能简单地通过引用访问。一个例子是std::vector < bool >:它在存储中的每个字节(每个位一个)中打包了8个bools。通过这种方式存储它们,不可能返回对单个此类bool的引用,因此index运算符返回一个“代理对象”,以支持所包含的bools的读取和写入。

如果可以返回对存储对象的直接引用,则除非希望限制赋值(例如,只允许容器中的正值),否则在代理中包装它没有真正的优势。

票数 4
EN

Stack Overflow用户

发布于 2014-04-10 06:37:48

通常,当您希望返回与数据的内部存储不匹配的内容时,将使用代理。典型的例子是一个2D矩阵,元素存储在一个数组中。如果提供返回行或列的运算符,则需要代理。另一个例子是臭名昭著的std::vector<bool>,它不需要将数据存储为bool块,但是access必须将bool返回给用户。

代理可用于返回内部数据表示的段的不同“视图”。在您的例子中,似乎没有理由使用它们。

票数 2
EN

Stack Overflow用户

发布于 2014-04-10 08:15:29

为大多数客户端使用正确的代理对象要复杂得多.例如-如果有人说:

代码语言:javascript
运行
复制
tcp_peer.send_from_iterator_range(&sample[2], &sample[7+1]);

如果sample::operator[]返回一个临时代理,而该代理没有仔细地替换operator&,那么代码将询问代理本身的地址。

有些客户端的使用不能在不失去代理拦截读取和/或写入数据的能力的情况下被支持,例如

代码语言:javascript
运行
复制
Container::element_type& ref = container[n];
ref = 20;

...the客户端代码假定容器的operator[]将产生对实际元素的引用。operator[]返回的任何代理都必须提供一个operator element_type&() --提交这样的引用并退出操作--或者拒绝(例如,只返回const引用,返回非const引用不能绑定到的临时值),并强制对客户端代码进行编辑。

所以,当你需要代理的时候,它的质量是95%,但如果你不需要的话,最好避免。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22980171

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档