Как получить ссылку на отрицание bool? - PullRequest
0 голосов
/ 14 апреля 2019

Например, если у меня есть значение bool v, я хочу ссылку на! V, которая может меняться при изменении v. Пример использования будет:

class A {
    bool& isOpen;
    A(bool& value): isOpen(value) {}
    void f() {
        if (isOpen) {
            doSomething();
        }
    }
};

class B {
    bool& isClosed;
    B(bool& value): isClosed(value) {}
    void g() {
        if (isClosed) {
            doSomething();
        }
    }
};

int main() {
    bool isOpen = true;
    A a(isOpen);
    B b(negattive_reference_of(isOpen));
    a.f(); // doSomething()
    b.g(); // do nothing
    isOpen = false;
    a.f(); // do nothing
    b.g(); // doSomething()
}

Есть ли в C ++ такой же эффект?

1 Ответ

0 голосов
/ 15 апреля 2019

Под капотом ссылка эквивалентна константному указателю на некоторую переменную (компилятор просто дает вам синтаксический сахар того, как работать с такими указателями, чтобы они всегда инициализировались).Таким образом, вы не хотите иметь одну и ту же переменную и два разных указателя на нее, один из которых будет ссылаться на true, а другой на false.Это, очевидно, невозможно.OOP-способ сделать это - передать не ссылку на логическое значение, а некоторый интерфейс к вашим классам и использовать реализацию, использующую ту же самую логическую переменную:

class IIsOpenProvider
{
public:
    virtual ~IIsOpenProvider() = 0;
    virtual bool GetOpenValue() = 0;
};

class IIsClosedProvider
{
public:
    virtual ~IIsClosedProvider() = 0;
    virtual bool GetClosedValue() = 0;
};

class ValueProvider : public IIsOpenProvider, public IIsClosedProvider
{
public:
    bool GetOpenValue() override { return isOpen; }
    bool GetClosedValue() override { return !isOpen; }

private:
    bool isOpen;
};

class A {
    IIsOpenProvider& isOpen;
    A(IIsOpenProvider& value): isOpen(value) {}
    void f() {
        if (isOpen.GetOpenValue()) {
            doSomething();
        }
    }
};

class B {
    IIsClosedProvider& isClosed;
    B(IIsClosedProvider& value): isClosed(value) {}
    void g() {
        if (IIsClosedProvider.GetClosedValue()) {
            doSomething();
        }
    }
};

// usage
ValueProvider val;
A a(val);
B b(val);
...