Class variables: public access read-only, but private access read/write

后端 未结 12 633
感动是毒
感动是毒 2020-11-28 05:25

Whoopee, not working on that socket library for the moment. I\'m trying to educate myself a little more in C++.

With classes, is there a way to make a variable read-

相关标签:
12条回答
  • 2020-11-28 06:20

    A simple solution, like Rob, but without contructor:

    class myClass {
        private:
        int m_x=10; // Note: different name than public, read-only interface
        public:
        const int& x=m_x;
    
    };
    
    int main() {
        myClass temp;
    
        // temp.x is const, so ...
        cout << temp.x << endl; // works
        // temp.x = 57;  // fails
    
    }
    

    Is like a get methode, but shorter. Interesant question ... something like. extent const bool member; can save a lot of getters ...but I don't know languages with this feature...

    0 讨论(0)
  • 2020-11-28 06:22

    There is a way to do it with a member variable, but it is probably not the advisable way of doing it.

    Have a private member that is writable, and a const reference public member variable that aliases a member of its own class.

    class Foo
    {
      private:
          Bar private_bar;
    
      public:
          const Bar& readonly_bar; // must appear after private_bar
                                  // in the class definition
    
      Foo() :
           readonly_bar( private_bar )
      {
      }
    };
    

    That will give you what you want.

    void Foo::someNonConstmethod()
    {
        private_bar.modifyTo( value );
    }
    
    void freeMethod()
    {
        readonly_bar.getSomeAttribute();
    }
    

    What you can do, and what you should do are different matters. I'm not sure the method I just outlined is popular and would pass many code reviews. It also unnecessarily increases sizeof(Foo) (albeit by a small amount) whereas a simple accessor "getter" would not, and can be inlined, so it won't generate more code either.

    0 讨论(0)
  • 2020-11-28 06:24

    This may do what you want.

    If you want a readonly variable but don't want the client to have to change the way they access it, try this templated class:

    template<typename MemberOfWhichClass, typename primative>                                       
    class ReadOnly {
        friend MemberOfWhichClass;
    public:
        inline operator primative() const                 { return x; }
    
        template<typename number> inline bool   operator==(const number& y) const { return x == y; } 
        template<typename number> inline number operator+ (const number& y) const { return x + y; } 
        template<typename number> inline number operator- (const number& y) const { return x - y; } 
        template<typename number> inline number operator* (const number& y) const { return x * y; }  
        template<typename number> inline number operator/ (const number& y) const { return x / y; } 
        template<typename number> inline number operator<<(const number& y) const { return x <<y; }
        template<typename number> inline number operator>>(const number& y) const { return x >> y; }
        template<typename number> inline number operator^ (const number& y) const { return x ^ y; }
        template<typename number> inline number operator| (const number& y) const { return x | y; }
        template<typename number> inline number operator& (const number& y) const { return x & y; }
        template<typename number> inline number operator&&(const number& y) const { return x &&y; }
        template<typename number> inline number operator||(const number& y) const { return x ||y; }
        template<typename number> inline number operator~() const                 { return ~x; }
    
    protected:
        template<typename number> inline number operator= (const number& y) { return x = y; }       
        template<typename number> inline number operator+=(const number& y) { return x += y; }      
        template<typename number> inline number operator-=(const number& y) { return x -= y; }      
        template<typename number> inline number operator*=(const number& y) { return x *= y; }      
        template<typename number> inline number operator/=(const number& y) { return x /= y; }      
        template<typename number> inline number operator&=(const number& y) { return x &= y; }
        template<typename number> inline number operator|=(const number& y) { return x |= y; }
        primative x;                                                                                
    };      
    

    Example Use:

    class Foo {
    public:
        ReadOnly<Foo, int> x;
    };
    

    Now you can access Foo.x, but you can't change Foo.x! Remember you'll need to add bitwise and unary operators as well! This is just an example to get you started

    0 讨论(0)
  • 2020-11-28 06:29

    You would have to leave it private and then make a function to access the value;

    private:
    
        int x;
    
    public:
    
        int X()
        {
            return x;
        }
    
    0 讨论(0)
  • 2020-11-28 06:29

    You need to make the member private and provide a public getter method.

    0 讨论(0)
  • 2020-11-28 06:32

    but temp.x = 5; not allowed?

    This is any how not allowed in the snippet posted because it is anyhow declared as private and can be accessed in the class scope only.

    Here are asking for accessing

    cout << temp.x << endl;

    but here not for-

    int myint = temp.x;

    This sounds very contradictory.

    0 讨论(0)
提交回复
热议问题