如何为班级成员创建一个开关?

时间:2012-12-20 03:43:18

标签: c++ class switch-statement

假设我有一个包含几个数据成员的类,我想要一个返回一个的类方法,下次调用它时会返回另一个的值。类似的东西:

class MyClass
{
    public:
        MyClass():switch(0){};
        int get();
    private:
        int intA, intB;
        int sw;
};        
int MyClass::get()
{ 
    if ( (++sw)%2 )
        return intA;
    else
        return intB;
}

更优雅的做法是什么?我非常不喜欢if ... else语句。这对于返回这样的东西很好,但是如果我实际上使用了更复杂的操作,我最终会复制大量的代码。或者必须在我解析我指向的元素后调用的每个方法中创建第二个方法。

我最喜欢做的是使用某种形式的指针,所以我可以做

class MyClass
{
    public:
        MyClass():switch(&intA){};
        int get();
        void toggleSwitch();
    private:
        int intA, intB;
        int * sw;
};        
int MyClass::get()
{
    return *sw;
}
void MyClass::toggleSwitch()
{
    if ( sw == &intA )
        sw = &intB;
    else
        sw = &intA;
}

或者那种效果。我可以调用toggleSwitch(),让我的类很容易在一个或另一个值上运行。

我仍然不喜欢它。我希望尽可能避免,如果可能的话,我不应该在这种情况下需要一个。这种裸指针的使用应该是非常安全的,但我认为我可以使用std :: unique_ptr来保存每个元素然后std :: swap它们。但是指针会拥有元素,而它们将成为动态内存。

那么有更好的方法吗?

2 个答案:

答案 0 :(得分:3)

嗯,switch是一个关键字,但我会随之滚动。一个指针数组怎么样?

int *fields[] = {&intA, &intB};

int MyClass::get()
{
    return *fields[++switch % 2];
}

如果以后可以使用其他变量,这将很好地扩展。

或者也许:

int MyClass::get()
{
    return *fields[switch = 1 - switch];
}

如果您返回引用,则可以在内部使用get()。

int &MyClass::get()
{
    return *fields[switch = 1 - switch];
}

答案 1 :(得分:0)

我会封装一个切换值的概念:

template<typename T>
class Toggleable {
    T first;
    T second;
    T* current;
    T* other;

public:
    Toggleable(const T& first, const T& second)
    : first(first),
      second(second),
      current(&first),
      other(&second) {
    }

    bool toggle() {
        std::swap(current, other);
    }

    const T& get() const {
        return *current;
    }
}

然后用作:

class MyClass
{
    Toggleable<int> value;

    public:
        MyClass()
        : value(42, 1729)
        {
        }

        const int& get() {
            value.toggle();
            return value.get();
        }
};