【问题标题】:Overload class function operator twice as setter and getter重载类函数运算符两次作为 setter 和 getter
【发布时间】:2015-01-31 18:09:41
【问题描述】:

我有一个类,我想重载函数调用运算符。但是由于 C++ 标准禁止声明两个仅在返回类型上不同的类似方法,所以我得到编译错误 C2556。我想将这些函数用作 getter 和 setter 方法。我知道我可以通过创建getset 函数来实现这一点。所以问题是:有没有办法以某种方式实现这一目标?

class Foo
{
    private:
        std::vector<int> m_vec;

    public:
        Foo()
        {
            m_vec.push_back(1);
            m_vec.push_back(2);
            m_vec.push_back(3);
        }

        //Getter
        int operator()(int i)
        {
            return m_vec.at(i);
        }

        //Setter (C2556)
        int& operator()(int i)
        {
            return m_vec.at(i);
        }
};

int main()
{
    Foo foo;
    foo(1) = 10; //use the setter 
    int i = foo(1); //use the getter
    return 0;
}

【问题讨论】:

    标签: c++ function operator-keyword


    【解决方案1】:

    解决这个问题的传统方式是使用const,如:

    #include <vector>
    
    class Foo
    {
        private:
            std::vector<int> m_vec;
    
        public:
            Foo()
            {
                m_vec.push_back(1);
                m_vec.push_back(2);
                m_vec.push_back(3);
            }
    
            //Setter
            int& operator()(int i)
            {
                return m_vec.at(i);
            }
            //getter
            int operator()(int i) const
            {
                return m_vec.at(i);
            }
    };
    
    int main()
    {
        Foo foo;
        foo(1) = 10; //use the setter 
        int i = foo(1); //use the getter
        const Foo& b = foo;
        int j = b(1);
        return 0;
    }
    

    现在,当您想要修改与不修改对象时,编译器将使用“适当的”方法。 (如果您曾经在 const 设置中使用 Foo,则只需要 const 运算符)

    【讨论】:

    • 那么这段代码 foo(1) = 10;导致错误 C2106:'=':左操作数必须是左值
    • @DmitryIlukhin 这是正确答案,我没有看到您的左值错误消息 - 您能提供一个示例吗?
    • Setter 有&amp;,getter 没有?
    • 这似乎不起作用。 foo(1) = 10;int i = foo(1); 都调用 setter。 Example.
    【解决方案2】:

    据我了解,第一次重载是不必要的。超载就够了

    int& operator()(int i)
    {
        return m_vec.at(i);
    }
    

    然后充当 getter 和 setter。该主题还讨论了here

    【讨论】:

    • 但它不适用于 const 对象,getter 应该适用于它们
    • 啊抱歉,我没有说我需要这两种方法,因为我的类有点复杂,如果使用 setter 函数,我还需要做其他几件事。
    • @AquilaRapax 那么我认为这是不可能的。你的操作员不知道它是用在赋值的左边还是右边。
    • @WojtekSurowka 不幸的是不是,除非我将Foo 声明为const(如解决方案中所述)。
    • @AquilaRapax 将变量声明为const 只是为了使用getter 不太实用。
    猜你喜欢
    • 1970-01-01
    • 2018-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多