I'm really new to C++ and one of the first things that has me really stumped is how to write a getter/setter that can use dot notation to get at a property.
For instance, instead of:
myObj.getAlpha();
it would be
myObj.alpha;
Is using dot notation like this frowned upon in C++ or is it just a pain to setup? I've had a hard time tracking down examples that weren't totally over my head so any guidance is much appreciated!
You can actually implement a getter and setter to a field like
myObj.alpha
but that is hard to setup and requires a proxy class.
The way for doing this is:
template<typename T>
class SetterProxy
{
T *m_T;
public:
SetterProxy(T &property) : m_T(&property) { }
SetterProxy(const SetterProxy&) = delete;
SetterProxy operator =(const SetterProxy&) = delete;
operator T&()
{
return *m_T;
}
T &operator =(T &other)
{
*m_T = other;
return *m_T;
}
}
class MyClass
{
int m_alpha;
public:
SetterProxy<int> alpha;
MyClass() : alpha(m_alpha) { }
}
"Properties" in other programming languages are mostly a quick shorthand - a superficial shorthand for a pair of function calls. The other benefits (like metadata) don't really exist in C++. You have the following options:
Make your own "properties". In other words, a getProperty() and setProperty() pair of functions.
Expose a member variable as public. If you only want to expose a "getter", expose a public const reference to a member variable.
As others are saying, write a class which you expose as a public member function, but handles the getting / setting so you can "intercept" it. This is, imo, way too much effort for whatever benefit it can provide.
I would suggest going with the simplest option for you, without giving up type safety & encapsulation. As long as the compiler still prevents external classes from messing things up in your class, public member variables are fine.
Consider accessing the property using the proposed notation.
alpha is obviously a member of the class, let's say of type member_t. Let's also say that the property you intend to add is of type prop_t. Now if member_t is the same as prop_t you haven't really made a property because you have provided free access to the underlying member, so let's assume that member_t is different from prop_t.
It then follows that member_t must have an implicit conversion to prop_t (which is doable, but usually frowned upon).
It also means that member_t must override the assignment operator to store the value provided to it when you set it.
Finally, you have to add getter and setter methods to the class which implement the get/set logic, and have member_t aggregate pointers to these functions as members (so that it can call the getter inside the implicit conversion to prop_t and call the setter inside the overridden assignment operator).
All of the above is certainly doable, but why would you want to write all this code? There is no tangible benefit at all, and doing it just for the sake of making C++ look like a language it is not won't earn you much support.
The easiest way is to have alpha as just an accessible (probably public) attribute of the class, or a variable!
class Obj
{
public:
char alpha;
Obj()
:alpha('a')
{
}
};
int main()
{
Obj myObj;
char letter = myObj.alpha;
// [...]
}
C++ doesn't have the "properties" that you are looking for.
If alpha is a public property of the class - you can do that. Nothing special to write for that, its built in.
You would use getters/setters for protected/private properties, because they're not directly accessible from outside (because, well, they're protected/private).
(by property I mean a class data member/variable, that's how its called in C++ usually).
You could declare your member variables public, then you don't need a function to access them. However this is normally not good practice.
Personally, I strongly agree with get\set accessors - others may argue otherwise, and they are entitled to their own opinion.
With C++, there is no official way to create a property, however there are some compiler-specific methods that you can use to expose properties as you would in, for example, C#.
With Microsoft Visual C++, you can use the properties as is described here: http://msdn.microsoft.com/en-us/library/yhfk0thd%28v=vs.80%29.aspx and I'm sure there are other methods of performing the same task on other compilers. Most of my code is written on and for the windows platform so I can exercise this luxury, if you are planning on working with a different compiler, you should avoid using this for obvious reasons.
There may be some sort of BOOST implementation that allows you to do it more safely, but don't quote me on that. - I know boost can do some pretty cool things though.
As to why people use getters and setters, well. To start, directly accessing an object's data sounds messy, but it also removes a lot of flexibility.
Consider with get\set accessors you can:
-More easily detect what is accessing your objects data
-Implement 'virtual variables' or rather, variables that contain data that must be generated per call.
-Redesign your object and possibly remove\redesign variables without having to worry about backwards compatibility
-Override the get\set accessors or implement them form an inherited interface.
I'm probably missing a couple reasons as well.
I posted on the my Italian blog a post where I explain a way to emulate the property construct of the CBuilder in the C++ standard. Just as reference here I report a class declaration called CPanel using the CBuilder syntax for property definition:
class CPanel
{
private:
int m_Width; // Private member for Width property
int m_Height; // Private member for Height property
protected:
void __fastcall SetWidth(int AValue); // Set the Width property
int __fastcall GetWidth(); // Get the Width property
void __fastcall SetHeight(int AValue);// Set the Height property
int __fastcall GetHeight(); // Get the Height property
public:
CPanel()
{
}
__property int Width = {read=GetWidth, write=SetWidth};
__property int Height = {read=GetHeight, write=SetHeight};
}
As you see the the syntax is very simple, you can define the private members m_Height and m_Width, the protected setter and getter methods and finally you can define your properties using the special keyword called __property. The following code shows you how to use the properties in your main function:
int main()
{
CPanel Panel;
Panel.Width = 10;
Panel.Height = 10;
int TmpWidth = Panel.Width;
int TmpHeight = Panel.Height;
}
We can emulate the same syntax defining a template class for our generic property, the following code shows a definition of a template class for this purpose:
template<typename owner_t,
typename prop_t,
void (owner_t::*setter)(prop_t),
prop_t (owner_t::*getter)()>
class CProperty
{
public:
// Constructor
CProperty(owner_t* owner){m_owner = owner;}
// op = overloading
void operator=(prop_t value)
{
return (m_owner->*setter)(value);
}
// op type overloading
operator prop_t()
{
return (m_owner->*getter)();
}
private:
prop_t* m_owner;
}
Thanks the above template we can redefine our CPanel class using the standard c++ language:
class CPanel
{
private:
int m_Width; // Private member for Width property
int m_Height; // Private member for Height property
protected:
void SetWidth(int AValue); // Set the Width property
int GetWidth(); // Get the Width property
void SetHeight(int AValue);// Set the Height property
int GetHeight(); // Get the Height property
public:
CPanel()
:Width(this), Height(this)
{
}
CProperty<CPanel, int, SetWidth, GetWidth> Width;
CProperty<CPanel, int, SetHeight, GetHeight> Height;
}
As you can see the syntax is very similar, but now it is standard. You can use the new CPanel class like previous main function:
int main()
{
CPanel Panel;
Panel.Width = 10;
Panel.Height = 10;
int TmpWidth = Panel.Width;
int TmpHeight = Panel.Height;
}
Here is a link to the full post (in Italian language)
I believe you are coming from objective C?
In C++, getters and setters are just methods, and functions invokation always requires ().
You can make the property public, and use myObj.alpha to access it, although what you want is direct access, not a getter method.
Related
Say I have:
struct foo{
int bar;
int baz;
...
bool flag;
}
Can an access operator -> or . be overridden to detect if bar or any other member variable is modified ?
EDIT:
The purpose is if I have many member variables and any of them is changed, I have a quick way of setting a flag, instead of using setters to encapsulate all the variables, making the code verbose.
Your approach is flawed because even if you override access operators you will not catch pointers writing the actual memory.
If most of the variables have the same type you can use an enum for flags and a single function to set or get a specific variable.
For example:
private:
int bar;
int baz;
public:
enum IntVariables { varBar, varBaz };
bool flag;
void setVariable(int varId, int value) {
flag = true;
if (varId == varBar)
bar = value;
else if (varId == varBaz)
baz = value;
}
I considered the following approach:
Just use a wrapper class that can have any data type, but implement all operations. In this same wrapper class override operators, and use the wrapper class in other class that require any modifications of member variables to be detected.
template <class T>
class wrapper {
private:
T var;
... .. ...
public:
T doSomethingToVar(T arg);
... .. ...
//Wherever the variable is modified send out a notification to whomever needs to detect the changes.
};
Pros:
When declaring variables in whichever class needs to detect modification of variables, it is easy to declare using the wrapper, without much additional code.
To ensure modifications are detected, need to implement functions / getters / setters / overload operators to detect modifications. This is tricky, and requires some thought.
Cons:
Tricky to implement a general purpose wrapper that can detect all modifications, since complex types can have functions that modify themselves in ways one is not aware of.
Notes:
How to ensure that every method of a class calls some other method first?
This answer is a work in progress, and I think it may be useful to others and maybe just cool to know about eventually, so open to comments. Will keep updating.
Update:
While writing out the above answer, I considered a different approach, of shifting responsibility onto the member variable classes:
class DetectChanges{
void onDetectChanges(){
//This function should be called by all implementing classes when the class has changes.
}
Can make it a design choice that all member variables inherit from DetectChanges.
The above two approaches are what I'm considering now. Not a solution yet, but thought I would put it out for comments and see if eventually we can figure something out.
}
I am working with an existing C library (that I can't modify) where some structures have opaque fields that must be accessed through specific setters and getters, like in the following crude example (imagining x is private, even though it's written in C).
struct CObject {
int x;
};
void setCObjectX(CObject* o, int x) {
o->x = x;
}
int getCObjectX(CObject* o) {
return o->x;
}
I am writing classes that privately own these types of structures, kind of like wrappers, albeit more complex. I want to expose the relevant fields in a convenient way. At first, I was simply writing setters and getters wherever necessary. However, I thought of something else, and I wanted to know if there are any downsides to the method. It uses function pointers (std::function) to store the C setter-getter pairs and present them as if directly accessing a field instead of functions.
Here is the generic class I wrote to help define such "fake" fields:
template<typename T>
struct IndirectField {
void operator=(const T& value) {
setter(value);
}
auto operator()() const -> T {
return *this;
}
operator T() const {
return getter();
}
std::function<void(const T&)> setter;
std::function<T()> getter;
};
It is used by defining an instance in the C++ class and setting up setter and getter with the corresponding C functions:
IndirectField<int> x;
// ...
x.setter = [=](int x) {
setCObjectX(innerObject.get(), x);
};
x.getter = [=]() {
return getCObjectX(innerObject.get());
};
Here is a complete, working code for testing.
Are there any disadvantages to using this method? Could it lead to eventual dangerous behaviors or something?
The biggest problem I see with your solution is that std::function objects take space inside each instance of IndirectField inside CPPObject, even when CObject type is the same.
You can fix this problem by making function pointers into template parameters:
template<typename T,typename R,void setter(R*,T),T getter(R*)>
struct IndirectField {
IndirectField(R *obj) : obj(obj) {
}
void operator=(const T& value) {
setter(obj, value);
}
auto operator()() const -> T {
return *this;
}
operator T() const {
return getter(obj);
}
private:
R *obj;
};
Here is how to use this implementation:
class CPPObject {
std::unique_ptr<CObject,decltype(&freeCObject)> obj;
public:
CPPObject()
: obj(createCObject(), freeCObject)
, x(obj.get())
, y(obj.get()) {
}
IndirectField<int,CObject,setCObjectX,getCObjectX> x;
IndirectField<double,CObject,setCObjectY,getCObjectY> y;
};
This approach trades two std::function objects for one CObject* pointer per IndirectField. Unfortunately, storing this pointer is required, because you cannot get it from the context inside the template.
Your modified demo.
Are there any disadvantages to using this method?
There's a few things to highlight in your code:
Your getters & setters, being not part of the class, break encapsulation. (Do you really want to tie yourself permanently to this library?)
Your example shows a massive amount of copying being done; which will be slower than it needs to be. (auto operator()(), operator T() to name but 2).
It's taking up more memory than you need to and adds more compexity than just passing around a Cobject. If you don't want things to know that it's a CObject, then create an abstract class and pass that abstract class around (see below for example).
Could it lead to eventual dangerous behaviors or something?
The breaking of encapsulation will result in x changing from any number of routes; and force other things to know about how it's stored in the object. Which is bad.
The creation of IndirectField Means that every object will have to have getters and setters in this way; which is going to be a maintenance nightmare.
Really I think what you're looking for is something like:
struct xProvider {
virtual int getX() const = 0;
virtual void setX() = 0;
};
struct MyCObject : xProvider {
private:
CObject obj;
public:
int getX() const override {return obj.x;}
CObject& getRawObj() {return obj;}
// etc ...
}
And then you just pass a reference / pointer to an xProvider around.
This will remove the dependence on this external C library; allowing you to replace it with your own test struct or a whole new library if you see fit; without having to re-write all your code using it
in a struct by default (as you post) all the fields are public, so they are accessible by client software. I you want to make them accessible to derived classes (you don't need to reimplement anything if you know the field contract and want to access it in a well defined way) they are made protected. And if you want them to be accessed by nobody, then mark them as private.
If the author of such a software doesn't want the fields to be touched by you, he will mark them as private, and then you'll have nothing to do, but to adapt to this behaviour. Failing to do will give you bad consequences.
Suppose you make a field that is modified with a set_myField() method, that calls a list of listeners anytime you make a change. If you bypass the method accessing function, all the listeners (many of them of unknown origin) will be bypassed and won't be notified of the field change. This is quite common in object programming, so you must obey the rules the authors impose to you.
As a C++ beginner, I didn't thought about that much until now, but if I want to access an attribute from inside a class itself, should I access the attribute directly or use a getter function?
class foo
{
public:
int getVal();
void bar();
private:
int val;
}
foo::bar()
{
int val = this->getVal();
// or
int val2 = this->val;
}
I would like to know that for
a) what is better design and (more importantly for me)
b) any performance differences (maybe because of the overhead calling the function)?
I normally use the getter method even inside the class in case I ever want to rename the attribute. But now I'm writing a method, which will access the attribute quite (very) often.
It depends. Getters may have synchronization and if called from a method that is already holding the lock may deadlock the application. Or, on the contrary, getters may count/log access to the resource. Or even, the class may be an interface on the byte buffer and getters/setters dynamically unmarshal/marshal the wire data, in which case calling getters and setters is unavoidable.
The only universal rule - be consistent across the code base and try to not overcomplicate the design.
Inside the class always use the attribute itself. The reason you have a getter is to make a certain value available to other classes. Be careful with automatically making getters for every attribute you use. It is considered bad design to expose the inner workings of a class. Sometimes it makes sense to make an attribute available, sometimes it is just for internal use and other classes have no business inspecting them.
If you like to know more about this google "getters setters evil" Some of the articles you may find are quite extreme but they will explain why they feel that way.
I disagree with #user3535256. Getters and setters should also be used inside private class functions. The idea behind getters and setters is to make code changes nice and easy. #StanE think of a situation where you're using your class member variable without getter functions and after some time you'd like to change the name to be more meaningful. This example forces you to change the member name in each place it's used. In case of using getter method for your variable only class getter function will be affected by this code change.
Basically, getter and setters are used to hide complexity, or better saying, to abstract details from out of a class. So they are not mandatory for using inside a class.
Simply I can say, if you don't have a getter, you don't need to make that, for using inside of the class.
But if you have a getter, you should always use that, whether inside or outside of the class, as you might have applied some logic to the raw value inside getter.
This depends on the internals of your class. Suppose you have a simple class that holds a value and you want to count how often that value was accessed but there are different getter methods (I have to admit it is a quite contrived example). Instead of doing the bookkeeping in each of the methods it is easier to do it only once and use the getter also inside the class:
class CountedValue{
private:
int value;
int counter;
public:
CountedValue() : value(0),counter(0) {}
int getValue() const {
counter++;
return value;
}
int getMinusValue() const {
return - getValue();
}
// ... possibly more methods to retrieve the value
int getCounter() const { return counter;}
}
Actually with setters the benefit of using them also inside the class becomes more evident. You usually want to do bookkeeping and define the invariants of a member only once and not each time it can change.
For example:
class Rational {
private:
int numerator;
int denominator;
public:
void setNumerator(int n) { numerator = n; }
void setDenominator(int d) {
assert(d != 0 && "division by zero");
denominator = d;
}
void set(int n, int d) {
setNumerator(n);
setDenominator(n); // no need to check for 0 again
}
}
I have two classes that are used in a project. One class, Callback, is in charge of holding information from a callback. Another class, UserInfo, is the information that is exposed to the user. Basically, UserInfo was supposed to be a very thin wrapper that reads Callback data and gives it to the user, while also providing some extra stuff.
struct Callback {
int i;
float f;
};
struct UserInfo {
int i;
float f;
std::string thekicker;
void print();
UserInfo& operator=(const Callback&);
};
The problem is that adding members to Callback requires identical changes in UserInfo, as well as updating operator= and similarly dependent member functions. In order to keep them in sync automatically, I want to do this instead:
struct Callback {
int i;
float f;
};
struct UserInfo : Callback{
std::string thekicker;
void print();
UserInfo& operator=(const Callback&);
};
Now UserInfo is guaranteed to have all of the same data members as Callback. The kicker is, in fact, the data member thekicker. There are no virtual destructors declared in Callback, and I believe the other coders want it to stay that way (they feel strongly against the performance penalty for virtual destructors). However, thekicker will be leaked if a UserInfo type is destroyed through a Callback*. It should be noted that it is not intended for UserInfo to ever be used through a Callback* interface, hence why these classes were separate in the first place. On the other hand, having to alter three or more pieces of code in identical ways just to modify one structure feels inelegant and error-prone.
Question: Is there any way to allow UserInfo to inherit Callback publicly (users have to be able to access all of the same information) but disallow assigning a Callback reference to a UserInfo specifically because of the lack of virtual destructor? I suspect this is not possible since it is a fundamental purpose for inheritance in the first place. My second question, is there a way to keep these two classes in sync with each other via some other method? I wanted to make Callback a member of UserInfo instead of a parent class, but I want data members to be directly read with user.i instead of user.call.i.
I think I'm asking for the impossible, but I am constantly surprised at the witchcraft of stackoverflow answers, so I thought I'd ask just to see if there actually was a remedy for this.
You could always enforce the 'can't delete via base class pointer' constraint that you mentioned (to some extent) by making the destructor protected in the base class:
i.e.
// Not deletable unless a derived class or friend is calling the dtor.
struct Callback {
int i;
float f;
protected:
~Callback() {}
};
// can delete objects of this type:
struct SimpleCallback : public Callback {};
struct UserInfo : public Callback {
std::string thekicker;
// ...
};
As others have mentioned, you can delete the assignment operator. For pre-c++11, just make an unimplemented prototype of that function private:
private:
UserInfo& operator=(const Callback&);
struct UserInfo : Callback {
...
// assignment from Callback disallowed
UserInfo& operator=(const Callback&) = delete;
...
};
Note that the STL features a lot of inheritance without a virtual destructor. The documentation explicitly states that these classes are not designed to be used as base classes.
some examples are vector<>, set<>, map<> ....
Another approach is to consider private inheritance while providing an accessor method to reveal the Callback (in which case you may as well use encapsulation which is cleaner).
Yes, there's trickery you can use to keep the members in sync and update operator= automatically. It's ugly though, involving macros and an unusual way of using an include file.
CallBackMembers.h:
MEMBER(int, i)
MEMBER(float, f)
Elsewhere:
struct Callback {
#define MEMBER(TYPE,NAME) TYPE NAME;
#include "CallbackMembers.h"
#undef MEMBER
};
struct UserInfo {
#define MEMBER(TYPE,NAME) TYPE NAME;
#include "CallbackMembers.h"
#undef MEMBER
std::string thekicker;
void print(); // you can use the macro trick here too
UserInfo& operator=(const Callback& rhs)
{
#define MEMBER(TYPE,NAME) NAME = rhs.NAME;
#include "CallbackMembers.h"
#undef MEMBER
return *this;
}
};
There is no way to meet ALL the criteria you want.
Personally I think your idea to make it a member and then use user.call.i is the best and most clear option. Keep in mind that you write code that uses this just once, but you make up for it in maintainability (since your UserData never has to change) and readability (since it's 100% transparent to the end-use which attribute are part of the callback data and which are auxiliary).
The only other option that might make sense is to use private inheritance instead, and using the attribute or function into UserData. With this you still have to add one using when new data is added to callback, but you get your desired user.i syntax for clients.
I have a class that has the following variables/members:
First Name
Last Name
Age
Address
etc..
I want to create getter-methods for each of them that returns the values. This could become quite large depending on the class.
Is there a quicker or more object-oriented way that would allow me to do this just using one method? The only way I can think about is to have a method that takes a parameter of the name of the variable to be returned; however, the types for the method would change depending on if it was returning a string, int etc..
Does anyone have a solution?
Why do you need those values outside the class? If you have code that is not in Person that calls 4 or 5 Person GetWhatever() methods and glues the strings together, stuffs commas between them and so on, move that code into Person. Do that enough and no code outside Person needs to call your getters.
Some classes are logic-free, they just hold values, and they expect outside objects to do all the work. In C++, using a struct for that makes your intention clear. If you insist that code outside Person needs to arbitrarily access elements of Person, it's probably a struct, not a class. If you insist it's a class, prove it by adding some actual business logic to it.
No, there is no "better" way which is still object-oriented. You should define one public "getter" method for each private member variable which needs to be access outside the class. You should also define a setter method, if the variable is meant to be set from outside the class.
If you want easy to define setter/getter - make it on single member level. Make member template with setter/getter and define is as public element of your class:
template <class Type>
class Member {
public:
Member(const T& value = T()) : value(value) {}
void setValue(const Type& t) { value = t; }
T getValue() const { return value; }
private:
T value;
};
Use it in your class:
class Person {
public:
Member<std::string> firstName;
Member<std::string> lastName;
Member<std::string> address;
Member<unsigned> age;
};
And usage:
int main() {
Person one;
one.firstName.setValue("Joe");
one.age.setValue(33);
}
If your need some constraints (like range checking) then define some RangeCheckingMember template. If you need the members to be dependent on each others - then make relationship between them by pointers/references.
Consider making that parameter lookup using a template member function that takes a default value in a given type.
template<typename ValueType>
const ValueType& get(const KeyType& key, const ValueType& default value) {
...
};
You still have to enumerate (or otherwise list) a KeyType of all your values (or use std::string which might be fine in larger cases) and work back and forth with your storage on the ValueType.
So, this doesn't really help you much until you decide you need arbitrarily large or completely dynamic values. At this point, you need to implement a map which can hold any type which requires either hideous unions or a template wrapper derived class from a common base class used in the map.
The upside to this is that a getKeys() method can present all of the keys available in the class -- something quite useful for dynamic GUIs and message handling.
If you are using a library in which everything subclasses some Object class (QObject for example), you can use a map of (string, object) to hold all your data and then access it with:
Object get(string name) { return memebers[name]; }
members is std::map<std::string, Object>
You will need to use type casts of course.
Button* my_var = static_cast<Button*>(my_class.get("my_button"));
// get returns Object
You can also use Qt's property system if you use Qt. This is not standard c++, but qmake and moc work on many operating systems.
all right.since you know what you want.
void get(int flag, void *return_value)
get the return_value typd casting to what you want.
thanks