Read only attributes in C++ (class proposal)
Hello, I wanted to make some read only attributes on C++ so I made a class, named ReadOnly. This class will contain an internal private value, only “friend” classes could change this internally. Description: · A read only object will contains an internal value that can’t be changed outside the class. For example: ReadOnly<string> name = “Daniel”; To access its value: object.name, if you try: object.name = “other”, it won’t change it’s value because it’s a read only variable; you can change it’s value only inside the class the object is declared, you could change it like: name.value = “whatever”; · To set a value (outside the class) to a read only attribute you MUST specify a setter function (which can be static and contained inside the class), like: ReadOnly<int> age {ReadOnly::setAge, 1}; (optionally you can also set a default value to the attribute). Example of setter function: static bool setAge(const int& value) { return (value > 0 && value <= 150); } So if you you have an object and you want to change its value like this: object.age = 100; it will change its internal value only if the setter function (which is called internally) returns true. · The idea of doing all of this instead private variables and getters & setters is because this approach is closer to OOP than what is normally used; I mean if you have an object and you want to get an attribute value, what you need to do in most cases is something like: object.getAttribute(), you are calling a function to just take a look at an attribute, that shouldn’t make sense in OOP, that’s why I made all of this. It’s also similar to how you manage getters and setters in Swift, because they are embedded in the attribute and you don’t need to make other functions. :) I uploaded the project to github so everyone can take a look: https://github.com/illescasDaniel/ReadOnly https://github.com/illescasDaniel/ReadOnly — I wanted to know your opinion about the idea of the class and also about the implementation, I’d love to upload it to boost libraries but I want to know people opinion and make the class better. Thank you!
On Mon, Oct 17, 2016 at 5:36 AM, Daniel Illescas Romero
Hello, I wanted to make some read only attributes on C++ so I made a class, named ReadOnly. This class will contain an internal private value, only “friend” classes could change this internally.
Description:
· A read only object will contains an internal value that can’t be changed outside the class. For example: ReadOnly<string> name = “Daniel”; To access its value: object.name, if you try: object.name = “other”, it won’t change it’s value because it’s a read only variable; you can change it’s value only inside the class the object is declared, you could change it like: name.value = “whatever”;
· To set a value (outside the class) to a read only attribute you MUST specify a setter function (which can be static and contained inside the class), like: ReadOnly<int> age {ReadOnly::setAge, 1}; (optionally you can also set a default value to the attribute).
Example of setter function:
static bool setAge(const int& value) { return (value > 0 && value <= 150); }
So if you you have an object and you want to change its value like this: object.age = 100; it will change its internal value only if the setter function (which is called internally) returns true.
· The idea of doing all of this instead private variables and getters & setters is because this approach is closer to OOP than what is normally used; I mean if you have an object and you want to get an attribute value, what you need to do in most cases is something like: object.getAttribute(), you are calling a function to just take a look at an attribute, that shouldn’t make sense in OOP, that’s why I made all of this. It’s also similar to how you manage getters and setters in Swift, because they are embedded in the attribute and you don’t need to make other functions. :)
I uploaded the project to github so everyone can take a look: https://github.com/illescasDaniel/ReadOnly https://github.com/illescasDaniel/ReadOnly —
I wanted to know your opinion about the idea of the class and also about the implementation, I’d love to upload it to boost libraries but I want to know people opinion and make the class better.
With your ReadOnly class, what you gain in syntax sugar, you loose in performance and memory. I am not really worried about the performance of setting the value, because the number of gets is usually much greater than the number of sets, but you inccur an overhead of one function pointer (and a bool, may or may not matter depending on alignment of the wrapped type) per member, and you penalize data locality. For the occasional object here and there, no problem, but one should not abuse this. Say I have a class Color that has red, green, and blue properties, as floats, and I want to ensure all values lie in the [0.0, 1.0] interval. If I use ReadOnly on a 64-bit architecture, I end up using 48 bytes for the class (extra setters member + alignment) instead of 12 bytes! Now, if I create a, say, vector<Color> of several thousands of elements for processing, I not only eat up more memory, I get four times more cache misses! So one must be aware of the cost of using ReadOnly and evaluate if it is acceptable for their use case. A note aside, instead of having the setter only by a predicate, it could do the whole assignment, e.g. static void setColorComponent(float& c, float value) { c = std::min(1.0f, std::max(0.0f, value)); } static void setAge(int& a, int value) { if(value <=0 || value > 150) { throw invalid_age(value); // or whatever error reporting you want } else { a = value; } } This way, you can modify the input value instead of just refusing them. Plus, the user of ReadOnly has the full power to report errors as he/she wishes. And the default setter could become [](Type&, const Type&) { // report an error: exception, logging, whatever } With that you don't even need the boolean hasSetter member! -- François
participants (2)
-
Daniel Illescas Romero
-
Francois Duranleau