强制类实例为const

Dan*_*nra 1 c++

有没有办法强制只允许实例化类的const实例,并且编译器会将非const实例检测为错误?

Ant*_*ton 6

是否存在采用现有类的通用方法,并通过删除所有非const功能来"理解"它?

一种可能的解决方法是创建一个包装类,该类包含类的实例,并且只允许访问const对它的引用.

template<class T>
class Immutable {
public:
    template<typename... Args>
    Immutable(Args&&... args) : instance(forward<Args>(args)...) {
    }
    operator const T&() {
        return instance;
    }
    const T& get() const {
        return instance;
    }
private:
    Immutable& operator=(const Immutable& other) = delete;
    T instance;
};
Run Code Online (Sandbox Code Playgroud)

假设你有一个可变类Class:

class Class {
public:
    Class() : m_value(0) {
    }
    Class(const Class& other) : m_value(other.m_value) {
    }
    Class(int value) : m_value(value) {
    }
    Class(int x, int y) : m_value(x + y) {
    }
    void change(int value) {
        m_value = value;
    }
    int value() const {
        return m_value;
    }
private:
    int m_value;
};
Run Code Online (Sandbox Code Playgroud)

以下是如何Immutable<Class>使用:

void functionTakingConstReference(const Class& x) {
}

void functionTakingNonConstReference(Class& x) {
}

void functionTakingImmutableClass(Immutable<Class>& x) {
}

void functionTakingValue(Class x) {
}


int main(int argc, char *argv[])
{
    // Any constructor of Class can also be used with Immutable<Class>.
    Immutable<Class> a;
    Immutable<Class> b(1);
    Immutable<Class> c(2, 3);
    Immutable<Class> d(c);

    // Compiles and works as expected.
    functionTakingConstReference(a);
    functionTakingImmutableClass(a);
    functionTakingValue(a);
    cout << a.get().value() << endl;

    // Doesn't compile because operator= is deleted.
    // b = a;


    // Doesn't compile because "change" is a non-const method.
    // a.get().change(4);


    // Doesn't compile because the function takes a non-const reference to Class as an argument.
    // functionTakingNonConstReference(a);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)