为引用返回访问器定义获取和设置行为

时间:2012-07-31 17:53:07

标签: c++ interface reference operator-overloading

作为几个较大项目的一部分,我正在开发一个矩阵模板类,只有当块中元素的值从定义的初始化值改变时,才会动态分配块。这个类将用于一些相当复杂的数学运算,所以我试图让界面尽可能简单直观。我希望能够使用operator(row,col)通过引用访问矩阵元素,而不是使用get(row,col)和set(element)方法。

然而这成了问题,因为由于分配行为,set和get的操作需要不同,需要测试针对初始化值设置的值。这不能仅仅返回一个引用,所以我创建了一个包含引用的helper类,并且可以将其转换为正确的数据类型,然后返回。这是界面的结构:

template <class T>
class Container{

public:

    // Element class which contains a reference to a data element
    class Element{

    public:

        // Constructor -- Initialize the element reference
        Element(T & element) :  _element(element){}

        // Assignment operator -- SET
        Element & operator=(const T & that){
            _element = that;
            return *this;
        }

        // Element to element assignment -- GET that, SET this
        Element & operator=(const Element & that){
            this->_element = that._element;
            return *this;
        }

        // Implicit conversion operator -- GET
        operator T(){
            return _element;
        }

    private :

        T & _element; // Element reference

    };

    // Return an element class containing a reference to the element
    Element operator()(int index){
        return Element(_data[index]);;
    }

private:

    T _data[10];

};

它依赖于隐式转换,以便能够使用返回的Element类,就好像它是T类型一样。我对它进行了测试,它似乎适用于基类型的基本赋值和算术运算,但对于运算符,如递增和二进制移位不进行隐式转换,操作导致编译器错误。并且我假设我发现了许多其他问题,试图将它与T一起用作类结构,指针等。

这一点,以及依靠隐式转换来修正类的修正功能似乎非常糟糕的事实,让我觉得我需要提出另一种方法。有什么方法可以解决我目前的方法吗?我可能会采取其他一些方法吗?或者我应该放弃这个并使运算符(row,col)始终分配get和set方法仅在必要时分配?

1 个答案:

答案 0 :(得分:0)

你可以为你做很多魔术。

我想首先指出Blitz++Thrust作为一些好的教学示例。在第一种情况下,这些“魔术引用”大量用于通过子阵列访问数据区域等。第二种情况用于安全地从其他存储空间(例如GPU中)访问数据,自动处理数据下载/上传。

我建议关注常用用法;您的容器主要用于保存标量值吗?然后只提供常见的算术运算,如++,+ =等,转发给实际的实现。你会看到2中使用的方法。缺点是访问内部数据的成员有点不方便 - 但如果这是一个不常见的情况,那将是一个很好的权衡。