class A
{
public:
readonlyint x; // x can not modify out of this class
void f()
{
x = 100; // Correct
}
}
int main()
{
A a;
a.x = 50; // error !
return 0;
}
The popular and standard solution is using Setter/Getter:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
class A
{
int x;
public:
void setX(int x)
{
this->x = x;
}
int getX() const // The popular way is returning value of the private variable
{
returnthis->x;
}
};
Yes, though one of my pet peeves about C++ is that the moment you introduce a reference variable (const or not) as a data member of a class (struct) or even just a const non-reference, the class becomes copyable but not assignable. I don't understand the use of such a thing.
Because of that, I tend to prefer the get and set methods, however, as object oriented programming is supposed to model data flow, not the data itself, use of set/get methods generally implies that ownership of the data being set/get is in the wrong place.
I think you somewhat missed the point, Framework. :/
The point is that C++ doesn't have a keyword that permits a variable to be read but not modified by non-friends and non-members of a certain class. This article was meant to teach you how to do this in the absence of such a keyword.
Readonly to the outside class but read/write within the class, Obviously "const" won't do that!
Maybe you only know ANSI C/C++, but if you know about C++Builder or Delphi there is a syntax to make readonly variables:
1 2 3 4 5 6 7
class A
{
private:
int _x;
public:
__property int x = {read=_x};
}
More info:
The real problem is: We can not assign one object of this class to another object because of existence of reference variable.
And the solution is: Writing a copy-constructor and Operator overloading for assignment
moorecm, You are right and Setter/Getter is the best way but this is just another approach.
We use getter because we have to use it, because there is not another solution in C++ syntax.
Using setter in many cases is logical because we should aware of changing the value of a variable, but using getter only for returning the value of a variable is not always logical. In fact a variable is a variable not a Function or Method !
Masoud... I read it again. Still, a public getter is probably a better approach for the reasons I gave in my original post.
(C++ Builder / Delphi solutions don't interest me since they are vendor extensions and thus not portable).
The real problem is: We can not assign one object of this class to another object because of existence of reference variable.
And the solution is: Writing a copy-constructor
Careful with terminology. Your solution doesn't solve the problem since copy construction and assignment are two different operations in C++. A copy constructor will not help with assignment. A data member that is a reference makes the object copyable (ie, copy constructible) but not assignable.
I want to ask something. Why is Masoud's class not assignable? I understand the general rule that adding a (const) reference member makes the class not assignable, but in this particular case this is not a problem, as that particular member doesn't need to be changed during the assignment. The only thing that needs to be changed is the real x, not the (public) fake one.
m4sterr0shi, why would I want to have to implement an assignment operator in order to have that proposed solution? It doesn't make things any easier does it?
moorecm, there is no benefit to returning a const reference to an integer unless you need to have a reference. It won't save you any time since a pointer has to be copied. The only reason to use a reference is if you needed to have a variable that would change when the underlying class attribute changes but if you need that then the design might be a problem. Moreover it could end up being very confusing for readers if you were to use that concept throughout a large scale program. You could easily lose track of which variables are truly local and which ones are really just pointers to private class attributes.
Anyway I don't see the lack of the readonly keyword as a weakness. C++ just happens to be a different language then C# and the designer had a different idea about how to do that. It seems like a waste of time to design work arounds to make make C++ look like C#. It's not the same language.
why would I want to have to implement an assignment operator in order to have that proposed solution? It doesn't make things any easier does it?
No, it doesn't. I don't disagree with that. Well, there is a way to make it work without providing an assignment operator. You could encapsulate the read-only functionality in a separate class and overload the assignment operator of that class to do nothing. Then you can use that class to build classes with read-only variables without having to overload the assignment operator again (the default assignment operator will call the overloaded assignment operator of the read-only class, which does nothing).
template <class T>
struct FriendMaker {typedef T Type;};
template <class T, class C>
class ReadOnly
{
friendclass FriendMaker<C>::Type;
private:
T data;
ReadOnly & operator=(const T & t) {data=t;}
public:
operatorconst T &() {return data;}
};
class MyClass
{
public:
ReadOnly<int,MyClass> x;
void SetX(int n) {x=n;}
};
kempofighter wrote:
Anyway I don't see the lack of the readonly keyword as a weakness.
Neither do I. But I find it challenging/entertaining to come up with such hacks/work-arounds.
At the very least, it can help one understand better how C++ works.