Thread: Read-only class members

  1. #1
    Registered User
    Join Date
    Oct 2005
    Posts
    43

    Read-only class members

    Hi,

    Suppose I have a class TClass. Now, I need a variable x of type TSomeType within that class to be passed to functions. However, the functions cannot "know" what type the class is (in this case, TClass) because they may receive variables from multiple different classes. Also I want x to be modifiable by the member functions of TClass, but not by any functions which x may be passed to.

    So for example, I cannot do something like this:

    Code:
    class TClass {
    private:
    TSomeType x;
    ...
    public:
    TSomeType Getx() {return x;};
    ...
    };
    
    void Function1(TClass *c) {
     TSomeType x1;
     x1 = c->Getx();
    ...
    }
    
    int main() {
     TClass class;
     Function1(&class);
    ...
    }
    The reason I can't do that is because then Function1 would have to "know" the type TClass. Also I can't do something like this:

    Code:
    class TClass {
    ...
    public:
    TSomeType x;
    };
    
    void Function2(TSomeType *y) {
     TSomeType y1 = &y;
    ...
    }
    
    int main() {
     TClass c;
     Function2(&(c->x));
    ...
    }
    because then Function2 could theoretically modify the value of y. Now I know that I could replace "TSomeType *y" with "const TSomeType *y" and that this would fix it in this particular case, but another function which was maybe written by someone else could leave out this "const" qualifier.

    So I suppose what I am asking is this: is there a way to make a class member so that it can only be modified by the class member functions themselves (like a private member) but that a pointer to it can still be passed to another function as a parameter if the parameter name is "const" qualified in the prototype (like a public member)?

    I have seen the word "const" used in front of variables rather than functions inside of a class definition, and am not sure if this will do what I need it to; in fact I am not sure of what THAT syntax means at all.

    One other thing. There is a fairly obvious way around this situation, but it's quite ugly and I'm sure that there would be a better way. It's to do this:

    Code:
    class TClass {
    private:
    TSomeType x;
    ...
    public:
    TSomeType y;
    ...
    };
    
    void Function3(TSomeType *z)
    {
     TSomeType z1 = &z;
    ...
    }
    
    int main()
    {
     TClass c;
     Function3(&(c->y));
    ...
    }
    and then simply make sure you set y equal to x after every class member function return which modifies x. However as I just said this is very ugly and perhaps even inefficient.
    Windows XP Professional SP2, Code::Blocks Studio 1.0rc2, GCC/G++ 3.4.2 (20040916-1), mingw32-make 3.80.0-3, GDB 5.2.1-1, W32API 3.6

    MingW Runtime 3.9, BinUitls 2.15.91 (20040904-1), MingW Utilities 0.3, Tcl/Tk 8.4.1-1

  2. #2
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    So I suppose what I am asking is this: is there a way to make a class member so that it can only be modified by the class member functions themselves (like a private member) but that a pointer to it can still be passed to another function as a parameter if the parameter name is "const" qualified in the prototype (like a public member)?
    Code:
    MyClass {
    private:
      int x;
    public:
      const int * getX(){ return &x; }
    };
    
    // ...
    
    void f (const int * p){
    }
    
    // ...
    
    MyClass m;
    f(m.getX());
    Like that?

    It's perfectly legal (though sometimes bad practice) to return a pointer to a private member, as long as the & operation is happening within the class (which is the only place you can access that variable). As you don't want it modifiable, return a pointer to const. You could also return a reference to const as well.
    Last edited by Cat; 10-13-2006 at 12:34 PM.
    You ever try a pink golf ball, Wally? Why, the wind shear on a pink ball alone can take the head clean off a 90 pound midget at 300 yards.

  3. #3
    Registered User
    Join Date
    Oct 2005
    Posts
    43
    Quote Originally Posted by Cat
    As you don't want it modifiable, return a pointer to const. You could also return a reference to const as well.
    Hmm. I don't really like const as much as private, because you can just cast a const variable to modify it.

    Code:
    fn(const int *p)
    {
     *((int *) p) = 1;
    }
    Also, the caller is not allowed to know anything about the type of class it is passed from. I got around both these problems by making a public "read-only" version of the class, which has a private pointer to the actual object itself, which is itself declared as private. Then I just wrapped the member functions of the new class back to the old one. Bit of a hack, but it seemed to work.

    Thanks for your help though, I didn't actually know that a function could return a pointer to a private variable.
    Windows XP Professional SP2, Code::Blocks Studio 1.0rc2, GCC/G++ 3.4.2 (20040916-1), mingw32-make 3.80.0-3, GDB 5.2.1-1, W32API 3.6

    MingW Runtime 3.9, BinUitls 2.15.91 (20040904-1), MingW Utilities 0.3, Tcl/Tk 8.4.1-1

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Normally you don't have to code to stop people from abusing the language. There are almost always tricks and techniques to get around language restrictions, but the point of things like const and private are to make clear what the restrictions are and assume the user of the class will follow them.

  5. #5
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    Quote Originally Posted by kidburla
    Hmm. I don't really like const as much as private, because you can just cast a const variable to modify it.
    There's really not much you can do to stop that. There are always ways to modify unmodifiable variables. Even private member variables can easily be manipulated with some compiler tricks.

    Also, the caller is not allowed to know anything about the type of class it is passed from.
    And in my code, it doesn't. It only knows the type that it is passed (const int *).
    Last edited by Cat; 10-14-2006 at 05:12 PM.
    You ever try a pink golf ball, Wally? Why, the wind shear on a pink ball alone can take the head clean off a 90 pound midget at 300 yards.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A question about class members and constructors
    By Megidolaon in forum C++ Programming
    Replies: 5
    Last Post: 01-30-2009, 03:01 PM
  2. Replies: 10
    Last Post: 07-26-2008, 08:44 AM
  3. "sorting news" assignment
    By prljavibluzer in forum C Programming
    Replies: 7
    Last Post: 02-06-2008, 06:45 AM
  4. Accessing members of parent class
    By Snip in forum C++ Programming
    Replies: 7
    Last Post: 06-29-2006, 01:28 PM
  5. Inheiritance and derived classes
    By pecymanski in forum C++ Programming
    Replies: 2
    Last Post: 12-09-2001, 03:50 PM