C++ - How to make read only class member variables

2019-07-31 09:47发布

Hi I am trying to make some public member variables read only. I know I could do something like:

private: int _x;
public: const int& x;
Constructor(): x(_x) {}


I'm looking for something more manageable and easier to read. I found several templates on the internet all of which do similar to what is described as a proxy class in this SO answer.

I'm trying to adapt that proxy class so that I can put the template in an include and write something like this for each variable in a class that I need read only variables in:

public: proxy<int, myClass> num;

Even easier would be if I didn't have to say the class name every time but I don't know a way to get around that unless the class name is identified in the template.

I tried this in Visual Studio 2010 but it doesn't work, does anyone know why?

template <class T, class C>
class proxy {
    friend class C;
private:
    T data;
    T operator=(const T& arg) { data = arg; return data; }
public:
    operator const T&() const { return data; }
};

class myClass {
public:
    proxy<int,myClass> x;

public:
    void f(int i) {
        x = i;
    }
};

Thanks

Edit- Someone asked for what I mean by doesn't work:

int main(int argc, char **argv)
{
    myClass test;
    test.f(12);
    cout << test.x << endl;
    return 0;
}

returns:

b.cpp(122) : error C2649: 'typename' : is not a 'class'
        b.cpp(128) : see reference to class template instantiation 'proxy<T,C>'
being compiled
b.cpp(136) : error C2248: 'proxy<T,C>::operator =' : cannot access private membe
r declared in class 'proxy<T,C>'
        with
        [
            T=int,
            C=myClass
        ]
        b.cpp(125) : see declaration of 'proxy<T,C>::operator ='
        with
        [
            T=int,
            C=myClass
        ]

2条回答
▲ chillily
2楼-- · 2019-07-31 10:37

Change this:

template <class T, class C>
class proxy {
  friend class C;

to this:

template <class T, class C>
class proxy {
   friend C;

Because C is a template parameter, it's not guaranteed that C will necessarily be a class type.

查看更多
成全新的幸福
3楼-- · 2019-07-31 10:38

I think that your problem is in design. You don't need a "public" members which is the encapsulation violation. I think that you are looking for something like IoC, take a look on visitor pattern it could help you:

class IStateHandler{
public:
  virtual void handleState( const proxy<int, myClass>& num )=0;
  virtual ~IStateHandler(){}
};

class myClass {
private:
    proxy<int,myClass> x;

public:
    void f(int i) {
        x = i;
    }

    void handleState( IStateHandler* stateHandler ){
       stateHandler->handle( x );
    }

};
查看更多
登录 后发表回答