AFAIK In C++, we call the getter/setter function as 'property'.
The getter/setter is used to get/set a member variable.
One of the advantages of doing this is that we can listen for change, like this:
// In header:
class XXX {
int m_width{};
void OnWidthChanged() {
// do something...
}
public:
int Width() const {
return m_width;
}
void Width(int val)
m_width = val;
this->OnWidthChanged();
}
};
// In CPP:
XXX my_xxx;
my_xxx.Width(123);
cout << my_xxx.Width() << endl;
Now I found static variable can be used to implement similar thing, in a non-OOP fashion I know it cannot handle multiple-instance, so let's just assume XXX is an object that has only 1 instance.
// In header:
int XXX_Width(bool set = false, int val = 0);
void XXX_OnWidthChanged();
// In CPP:
int XXX_Width(bool set, int val) {
static int width = 0;
if (set) {
width = val;
XXX_OnWidthChanged();
}
return width;
}
XXX_Width(true, 123);
cout << XXX_Width() << endl;
My question is, is there a name or term for this kind of functions functions like XXX_Width()?
I'm looking for a name so I can google search for related information.
I'm not asking for name for OnWidthChanged().
Lots of confusion about terminology here.
OOP simply means that you have autonomous classes with their functionality encapsulated. Both your examples use OO, though if they are bad or good design is another matter.
Now I found static variable can be used to implement similar thing, in a non-OOP fashion:
There is nothing non-OOP with your example. It is however probably bad OO design, since multiple instances of your class may access that same function. It is also bad design from a thread-safety perspective.
Sometimes, using static variables locally is perfectly fine though, like for example when implementing "singleton" classes.
In C++, we call the getter/setter function as 'property'
No, that is not a common term. Getter/setter functions are called members, or member functions. Or possibly public member functions, since by definition those must be public. Another term used for them is methods.
The term property is most often used to describe public member variables. Often RAD tools use the term property for such variables.
My question is, is there a name or term for this kind of functions?
A function which is specified by the caller, but called by someone else (the class, the OS, an interrupt etc) is universally called callback function. This is a fairly broad term.
In your case, you seem to use callback functions like "events" - an event is a kind of callback function but a higher level concept. Code like your example could be used for so-called "event-driven design", which is also popular among RAD tools.
The 1st point that should be made is that your "property block" or "getter/setter" are non-conformant. The expected declarations look like:
int Width() const;
void Width(const int);
So when you change the setter to: XXX& Width(int) it becomes clear that you aren't talking about "property blocks" or "getter/setters". So let's talk about what your setter does look like:
It makes a call after width changes. Such a call would typically be an interupt or a signal
It returns a non-const reference to the object. This is the behavior of an operator which notably do have outside class versions
Now let's talk about your function: int XXX_Width(bool set = false, int val = 0) You've set it up with default arguments such that it could behave as either the setter or the getter in your example, notwithstanding the weirdness of your getter's return.
Given the distinction between the 2 options you present, you seem to be asking:
Is there a name for using a functions static variable instead of defining a function and providing getter/setters for a member variable?
A function scoped static variable is called a static local variable.
One word of wisdom on static local variables:
A static local variable is different from a local variable as a static local variable is initialized only once no matter how many times the function in which it resides is called and its value is retained and accessible through many calls to the function in which it is declared [source]
Related
I have been looking around for a while now and can't seem to find an answer to this.
So, if I have several instances of a class, how can I call a function only once from all instances of that class?
For example, if I have a function called myFunc() within a class called myClass and two instances of that class called class1 and class2, then
class1.myFunc() should return 1,
class2.myFunc() should return 0, and
class1.myFunc() should return 0.
How would I do this?
class myClass{
public:
myClass(){}
int myFunc(){
if (myFuncHasBeenCalled){
return 0;
}
else{
return 1;
}
}
}
myClass class1;
myClass class2;
class1.myFunc(); //would output 1
class2.myFunc(); //would output 0
class1.myFunc(); //would output 0
You can achieve that by
introducing a class variable, using static keyword for it in class declaration
define the class variable in a (separate) code file, with initialisation
check it inside the function, if 0 output 1 else 0
increase (or set to non-zero) afterwards
be careful, using synchronisation mechanisms, in case the calls might be from different contexts/threads/tasks/processes (whatever is applicable in your environment)
(If you show your attempts with static variables and explain the problems you had, this could become more detailed.)
You have several options available: the idea is that you need to have some value that can be accessed independently of the instances of the class. static is the way to do this in all cases (except when it's not).
Option one is best option -- static variable in member functions
The approach I would recommend is using a static variable in the member function; this avoids polluting the class itself and makes it easier for you to maintain a consistent ABI as well as a consistent API, across updates. It is very easy to reason about your code as you're not allowing anything else to access the variable.
Example:
struct S {
int F() const {
static int n = 1;
if (n == 1) {
n = 0;
return 1;
}
return n;
}
};
Option two is bad option -- static variable in class
An alternative, which seems to be popular, is to keep a static member variable. This allows you do to the same thing as the previous example, but makes it harder to maintain the API and the ABI across upgrades. It also makes it harder to reason about your code and makes it easier to introduce bugs -- a static member variable is not much different from a global variable.
Example:
struct S {
static int n;
int F() const {
if (n == 1) {
n = 0;
return 1;
}
return n;
}
};
int S::n = 1;
Option three is worst option -- global variables
The worst alternative is to use a global variable. I'm not going to give you an example of this -- don't do it. If you must do it anyway (you don't), declare your variables in an anonymous namespace in your .cpp file.
namespace {
int n = 0
}
Options four -- good option
Another approach is to use a static member function. This functions is fully independent of all instance of the class. The only difference in the implementation is that you add static to the function declaration -- otherwise, you can use the first two options. This won't be possible in all situations though.
Caveats and other notes
If you need to use the variable to communicate state between two functions, you have to use one of the global options and cannot use a static variable in a member function.
In all cases, if you're not modifying the instance, you should mark your functions const.
You should really use std::atomic variables
You should use some sort of mechanism that guarantees that your code is threadsafe.
I am trying to do this C++ tutorial. I am a beginner in C++ programming. I don't get why they use setValue and getValue in class Class1 and not setClass1. In the other tutorial they use setA and getA in the class class Class1. Here are the codes:
class Class1 {
int i;
public:
void setValue( int value ) { i = value; }
int getValue() { return i; }
};
the second code is:
class A{
int ia;
public:// accessor method because they are used to access a private date member
void setA ( const int a);
int getA ()const;
int getA ();
};
Please help...
The names are arbitrary, you can use any function names you wish (subject to language rules, of course).
However, although you can use xyzzy() and plugh() as getter and setter, it's not really a good idea.
You should use something that indicates the intent of the call, such as getTemperature() or setVelocity(). And these don't even have to map one-to-one to internal fields since encapsulation means the internal details should not be exposed.
By that, I mean you may have a getTemperatureC() for returning the temperature in Celsius even though the internal field is stored as Kelvins:
double getTemperatureC(void) { return kelvins - 273.15; }
void setTemperatureC(double t) { kelvins = t + 273.15; }
(or a getter/setter may use arbitrarily complex calculations).
Using getA() for a class A may well cause you trouble when you create class B to inherit from A but this is outside the scope of the language. But it's good programming practice to follow the guideline above (functions should indicate intent rather than internals).
I was confused on why they use the same name in get and set with the class name, and different get and set name on the other class. Will the set and get names affect the code?
The answer is No.
getter and setter are usually called accessor and mutators in a class. They are just member functions named according to some convention, easy for people who read the code to understand the purpose of those functions, so it is like common sense to name those member function starting with get if you try to access the member variables and starting with set if you try to change some member variables. The names can be any valid identifier.
So setValue or setA are just identifiers for those member functions. It will not affect the code.
Meanwhile, different class can have the same named getter or setters since those function names are in different class scope.
The question is, what would be the best or maybe a better practice to use. Suppose I have a function, which belongs to some class and this function needs to use some static variable. There are two possible approaches - to declare this variable as class's member:
class SomeClass
{
public:
....
void someMethod();
private:
static int m_someVar;
};
SomeClass::someMethod()
{
// Do some things here
....
++m_someVar;
}
Or to declare it inside the function.
class SomeClass
{
public:
....
void someMethod();
};
SomeClass::someMethod()
{
static int var = 0;
++m_someVar;
// Do some things here
....
}
I can see some advantages for the second variant. It provides a better encapsulation and better isolates details of an implementation. So it would be easier to use this function in some other class probably. And if this variable should be modified only by a single function, then it can prevent some erroneous data corruption from other methods.
While it's quite obvious, that the first variant is the only one to use when you need to share a static variable among several methods (class functions), the question pertains the case when a static variable should be used only for a single function. Are there any advantages for the first variant in that case? I can think only about some multi threading related stuff...
It's simple - use a static member if, logically, it belongs to the class (sort of like instanceCounter) and use a static local if it logically belongs to a function (numberOfTimesThisMethodWasCalled).
The choice of static or not depends completely on the context. If a particular variable needs to be common among all the instances of a class, you make it static.
However, if a variable needs to be visible only in a function and needs to be common across every call of the function, just make it a local static variable.
The difference between static data members and static variable in a function is that first are initialized at start-up and the second first time the function is called (lazy initialization).
Lazy initialization can create problem when a function is used in a muti-threaded application, if it is not required by the design I prefer to use static members.
I understand that one benefit of having static member functions is not having to initialize a class to use them. It seems to me that another advantage of them might be not having direct access to the class's not-static stuff.
For example a common practice is if you know that a function will have arguments that are not to be changed, to simply mark these constant. e.g.:
bool My_Class::do_stuff(const int not_to_be_changed_1,
std::vector<int> const * const not_to_be_changed_2)
{
//I can't change my int var, my vector pointer, or the ints inside it.
}
So is it valid to use static member functions to limit access. For example, lets say you have a function
void My_Class::print_error(const unsigned int error_no) {
switch (error_no) {
case 1:
std::cout << "Bad read on..." << std::endl;
break;
//...
default:
break;
}
}
Well here we're not going to be accessing any member variables of the class. So if I changed the function to:
static void My_Class::print_error(const unsigned int error_no) {
switch (error_no) {
case 1:
std::cout << "Bad read on..." << std::endl;
break;
//...
default:
break;
}
}
I'd now get an error, if I inadvertently tried to access one of my private var, etc. (unless I pass myself an instance of my class, which would be purposeful ^_^ !)
Is this a valid technique, similar to proactively making args that should not be changed constants?
What downsides might it have in terms of efficiency or use?
My chief reason for asking is that most of the "static" tutorials I read made no mention of using it in this way, so I was wondering if there was a good reason why not to, considering it seems like a useful tool.
Edit 1: A further logical justification of this use:
I have a function print_error,as outlined above. I could use a namespace:
namespace MY_SPACE {
static void print_error(...) {
...
}
class My_Class {
....
void a(void)
}
}
But this is a pain, because I now have to lengthen ALL of my var declarations, i.e.
MY_SPACE::My_Class class_1;
all to remove a function from my class, that essentially is a member of my class.
Of course there's multiple levels of access control for functions:
//can't change pointer to list directly
void My_Class::print_error(std::vector<int> const * error_code_list) {...}
//can't change pointer to list or list members directly
void My_Class::print_error(std::vector<int> const * const error_code_list) {...}
//can't change pointer to list or list members directly, access
//non-const member vars/functions
void My_Class::print_error(std::vector<int> const * const error_code_list) const {...}
//can't change pointer to list or list members directly, access
//non-static member vars/functions
static void My_Class::print_error(std::vector<int> const * const error_code_list) {...}
//can't change pointer to list or list members directly, access
//member vars/functions that are not BOTH static and const
static void My_Class::print_error(std::vector<int> const * const error_code_list) const {...}
Sure this is a bit atypical, but to lessening degrees so are using const functions and const variables. I've seen lots of examples where people could have used a const function, but didn't. Yet some people think its a good idea. I know a lot of beginning c++ programmers who wouldn't understand the implications of a const function or a static one. Likewise a lot would understand both.
So why are some people so adamantly against using this as an access control mechanism if the language/spec provides for it to be used as such, just as it does with const functions, etc.?
Any member function should have access to the other members of the object. Why are you trying to protect yourself from yourself?
Static members are generally used sparingly, factory methods for example. You'll be creating a situation that makes the next person to work with your code go "WTF???"
Don't do this. Using static as an access-control mechanism is a barbaric abomination.
One reason not to do this is because it's odd. Maintenance programmers will have a hard time understanding your code because it's so odd. Maintainable code is good code. Everybody gets const methods. Nobody gets static-as-const. The best documentation for your code is the code itself. Self-documenting code is a goal you should aspire to. Not so that you don't have to write comments, but so that they won't have to read them. Because you know they're not going to anyway.
Another reason not to do this is because you never know what the future will bring. Your print_error method above does not need to access the class' state -- now. But I can see how it one day might need to. Suppose your class is a wrapper around a UDP socket. Sometime in the middle of the session, the other end slams the door. You want to know why. The last messages you sent or received might hold a clue. Shouldn't you dump it? You need state for that.
A false reason to do this is because it provides member access control. Yes it does this, but there are already mechanisms for this. Suppose you're writing a function that you want to be sure doesn't change the state of the object. For instance, print_error shouldn't change any of the object's state. So make the method const:
class MyClass
{
public:
void print_error(const unsigned int error_no) const;
};
...
void MyClass::print_error(const unsigned int error_no) const
{
// do stuff
}
print_error is a const method, meaning effectively that the this pointer is const. You can't change any non-mutable members, and you can't call any non-const methods. Isn't this really what you want?
Static member functions should be used when they are relevant to the class but do not operate on an instance of the class.
Examples include a class of utility methods, all of which are static because you never need an actual instance of the utility class itself.
Another example is a class that uses static helper functions, and those functions are useful enough for other functions outside the class.
It is certainly fair to say that global scope functions, static member functions, and friend functions aren't quite orthogonal to one another. To a certain extent, this is largely because they are intended to have somewhat different semantic meaning to the programmer, even though they produce similar output.
In particular, the only difference between a static member method and a friend function is that the namespaces are different, the static member has a namespace of ::className::methodName and the friend function is just ::friendFunctionName. They both operate in the same way.
Well, actually there is one other difference, static methods can be accessed via pointer indirection, which can be useful in the case of polymorphic classes.
So the question is, does the function belong as "part" of the class? if so, use a static method. if not, put the method in the global scope, and make it a friend if it might need access to the private member variables (or don't if it doesn't)
Several questions about accessor methods in C++ have been asked on SO, but none was able satisfy my curiosity on the issue.
I try to avoid accessors whenever possible, because, like Stroustrup and other famous programmers, I consider a class with many of them a sign of bad OO. In C++, I can in most cases add more responsibility to a class or use the friend keyword to avoid them. Yet in some cases, you really need access to specific class members.
There are several possibilities:
1. Don't use accessors at all
We can just make the respective member variables public. This is a no-go in Java, but seems to be OK with the C++ community. However, I'm a bit worried about cases were an explicit copy or a read-only (const) reference to an object should be returned, is that exaggerated?
2. Use Java-style get/set methods
I'm not sure if it's from Java at all, but I mean this:
int getAmount(); // Returns the amount
void setAmount(int amount); // Sets the amount
3. Use objective C-style get/set methods
This is a bit weird, but apparently increasingly common:
int amount(); // Returns the amount
void amount(int amount); // Sets the amount
In order for that to work, you will have to find a different name for your member variable. Some people append an underscore, others prepend "m_". I don't like either.
Which style do you use and why?
From my perspective as sitting with 4 million lines of C++ code (and that's just one project) from a maintenance perspective I would say:
It's ok to not use getters/setters if members are immutable (i.e. const) or simple with no dependencies (like a point class with members X and Y).
If member is private only it's also ok to skip getters/setters. I also count members of internal pimpl-classes as private if the .cpp unit is smallish.
If member is public or protected (protected is just as bad as public) and non-const, non-simple or has dependencies then use getters/setters.
As a maintenance guy my main reason for wanting to have getters/setters is because then I have a place to put break points / logging / something else.
I prefer the style of alternative 2. as that's more searchable (a key component in writing maintainable code).
2) is the best IMO, because it makes your intentions clearest. set_amount(10) is more meaningful than amount(10), and as a nice side effect allows a member named amount.
Public variables is usually a bad idea, because there's no encapsulation. Suppose you need to update a cache or refresh a window when a variable is updated? Too bad if your variables are public. If you have a set method, you can add it there.
I never use this style. Because it can limit the future of your class design and explicit geters or setters are just as efficient with a good compilers.
Of course, in reality inline explicit getters or setters create just as much underlying dependency on the class implementation. THey just reduce semantic dependency. You still have to recompile everything if you change them.
This is my default style when I use accessor methods.
This style seems too 'clever' to me. I do use it on rare occasions, but only in cases where I really want the accessor to feel as much as possible like a variable.
I do think there is a case for simple bags of variables with possibly a constructor to make sure they're all initialized to something sane. When I do this, I simply make it a struct and leave it all public.
That is a good style if we just want to represent pure data.
I don't like it :) because get_/set_ is really unnecessary when we can overload them in C++.
STL uses this style, such as std::streamString::str and std::ios_base::flags, except when it should be avoided! when? When method's name conflicts with other type's name, then get_/set_ style is used, such as std::string::get_allocator because of std::allocator.
In general, I feel that it is not a good idea to have too many getters and setters being used by too many entities in the system. It is just an indication of a bad design or wrong encapsulation.
Having said that, if such a design needs to be refactored, and the source code is available, I would prefer to use the Visitor Design pattern. The reason is:
a. It gives a class an opportunity to
decide whom to allow access to its
private state
b. It gives a class an
opportunity to decide what access to
allow to each of the entities who are
interested in its private state
c. It
clearly documents such exteral access
via a clear class interface
Basic idea is:
a) Redesign if possible else,
b)
Refactor such that
All access to class state is via a well known individualistic
interface
It should be possible to configure some kind of do's and don'ts
to each such interface, e.g. all
access from external entity GOOD
should be allowed, all access from
external entity BAD should be
disallowed, and external entity OK
should be allowed to get but not set (for example)
I would not exclude accessors from use. May for some POD structures, but I consider them a good thing (some accessors might have additional logic, too).
It doesn't realy matters the naming convention, if you are consistent in your code. If you are using several third party libraries, they might use different naming conventions anyway. So it is a matter of taste.
I've seen the idealization of classes instead of integral types to refer to meaningful data.
Something like this below is generally not making good use of C++ properties:
struct particle {
float mass;
float acceleration;
float velocity;
} p;
Why? Because the result of p.mass*p.acceleration is a float and not force as expected.
The definition of classes to designate a purpose (even if it's a value, like amount mentioned earlier) makes more sense, and allow us to do something like:
struct amount
{
int value;
amount() : value( 0 ) {}
amount( int value0 ) : value( value0 ) {}
operator int()& { return value; }
operator int()const& { return value; }
amount& operator = ( int const newvalue )
{
value = newvalue;
return *this;
}
};
You can access the value in amount implicitly by the operator int. Furthermore:
struct wage
{
amount balance;
operator amount()& { return balance; }
operator amount()const& { return balance; }
wage& operator = ( amount const& newbalance )
{
balance = newbalance;
return *this;
}
};
Getter/Setter usage:
void wage_test()
{
wage worker;
(amount&)worker = 100; // if you like this, can remove = operator
worker = amount(105); // an alternative if the first one is too weird
int value = (amount)worker; // getting amount is more clear
}
This is a different approach, doesn't mean it's good or bad, but different.
An additional possibility could be :
int& amount();
I'm not sure I would recommend it, but it has the advantage that the unusual notation can refrain users to modify data.
str.length() = 5; // Ok string is a very bad example :)
Sometimes it is maybe just the good choice to make:
image(point) = 255;
Another possibility again, use functional notation to modify the object.
edit::change_amount(obj, val)
This way dangerous/editing function can be pulled away in a separate namespace with it's own documentation. This one seems to come naturally with generic programming.
Let me tell you about one additional possiblity, which seems the most conscise.
Need to read & modify
Simply declare that variable public:
class Worker {
public:
int wage = 5000;
}
worker.wage = 8000;
cout << worker.wage << endl;
Need just to read
class Worker {
int _wage = 5000;
public:
inline int wage() {
return _wage;
}
}
worker.wage = 8000; // error !!
cout << worker.wage() << endl;
The downside of this approach is that you need to change all the calling code (add parentheses, that is) when you want to change the access pattern.
variation on #3, i'm told this could be 'fluent' style
class foo {
private: int bar;
private: int narf;
public: foo & bar(int);
public: int bar();
public: foo & narf(int);
public: int narf();
};
//multi set (get is as expected)
foo f; f.bar(2).narf(3);