I recently came across this class and was surprised at how the getters and
setters were implemented.
I have not come across this before and would welcome some second opinions.
Do you think this is a good paradigm?
Is is bad?
Is it evil?
Header:
class Tool
{
public:
Tool();
virtual ~Tool();
bool setName(const std::string &name);
bool getName(std::string &name) const;
void clearName();
private:
std::string m_name;
bool m_nameSet;
};
cpp file:
#include "Tool.h"
Tool::Tool()
: m_name("")
, m_nameSet(false)
{
}
Tool::~Tool()
{
}
bool Tool::setName(const std::string &name)
{
m_name = name;
m_nameSet = true;
return (m_nameSet);
}
bool Tool::getName(std::string &name) const
{
bool success = false;
if (m_nameSet)
{
name = m_name;
success = true;
}
return (success);
}
The way you selected for getter is not popular, programmers prefer to return data from getter
std::string getName() const;
Why an item that set before, or has an initial data, should be re-checked on getter? If you want validate the data, validate it on setter.
However if your insist to return a value as "is name set before", you can write a third method by means of bool isNameSet() const;
This looks a lot like C where it is usual to return status codes to see if a functions fails or not.
Then also there are better methods to verify that a name is set or not. One could be to use the boost::optional to me this is a better way to declare intent that the name might not be set at all times.
I would however wonder if it's not better to make sure the name is set at all times by only having one constructor that takes a std::string as a parameter.
class Tool
{
public:
//Constructor already does the right thing
Tool() = default;
virtual ~Tool();
//Use void or return the modified class, akin to operators
void setName(const std::string& name)
{
m_name = name;
}
//Alternatively
Tool& setName(const std::string &name)
{
m_name = name;
return *this;
}
//Return const reference to the value if possible, avoids copying if not needed
//This will fail at run time if name is not set
//Maybe throw an exception if that is preferred
const std::string& getName() const
{
return *m_name;
//Or
if(m_name) return *m_name;
else throw some_exception;
}
//Or return the optional, then calling code can check if name where set or not
const boost::optional<std::string>& getName() const
{
return m_name;
}
void clearName()
{
m_name = boost::optional<std::string>();
}
private:
boost::optional<std::string> m_name;
};
I wouldn't call that a paradigm. This seems to be a solution for architecture, where a field may be in unspecified state (why not? Sometimes it is a sane requirement). Though, I don't like much this solution, because getter is supposed to return value (symmetrically, setter is supposed to set it) and the convention usually requires specific prototypes:
Type GetValue();
SetValue (const Type & newValue);
or
SetValue (Type & newValue);
or
SetValue (Type newValue);
You shall choose one of three setters depending on situation, usually the first or second one fits.
If a field may be in an unspecified state, I would choose another approach, as M M. suggests in his answer, I'll take liberty to provide an example:
class C
{
private:
int field;
bool fieldSet;
public:
C()
{
field = 0;
fieldSet = false;
}
bool IsFieldSet()
{
return fieldSet;
}
int GetField()
{
if (!fieldSet)
throw std::exception("Attempt to use unset field!");
return field;
}
void SetField(const int newValue)
{
field = newValue;
fieldSet = true;
}
};
Note though, that I wouldn't call this way of implementing getters evil. It may be just uncomfortable to use.
Related
Here's what I want to create:
class Theme
{
public:
Theme();
bool isValid() const;
QString name() const;
private:
QString m_name;
};
class ThemeManager
{
public:
ThemeManager();
~ThemeManager();
void setCurrentTheme(const Theme& theme);
const Theme& currentTheme() const;
const Theme& theme(const QString& name) const;
private:
Theme& m_currentTheme;
QSet<Theme> m_availableThemes;
};
Here comes the tricky part:
const Theme& ThemeManager::theme(const QString& name) const
{
for (const Theme& theme : m_availableThemes)
{
if (name == theme.name())
{
return theme;
}
}
return Theme();
}
This is what I want to achieve:
ThemeManager m;
const Theme& t = theme("monokai");
if (t.isValid()) {
// Theme is valid
} else {
// Theme is not valid
}
ThemeManagers keeps a list of themes and a reference to the current one. I want to use references instead of pointers. Now if a theme it is asked for is not present in the manager's list of themes, I would like to return a reference to an invalid one which I can test using Theme::isValid. I wouldn't like to use a separate member e.g. Theme m_invalidTheme; just for this purpose.
My question is: isn't there any way to move a temporary object outside from ThemeManager::theme scope? So that t from t.isValid() is not a dangling reference which breaks the code?
Strange problem, already looked into with several colleagues...
Using Qt Creator and Qt 4.8.5
define an object
set a number of values with setters
request values with a getters
result: getting an int no problem, all other values give segmentation fault
but with breakpoint in debugger the values are correctly shown, so they are in the object!
same code worked before, problem "just appeared". Compiler issue?
private:
int id;
QString name;
public;
int getId() { return this->id; } // OK
void setId(int id) { this->id = id; }
QString getName() { return this->name; } // SIGSEGV
void setName(QString name) { this->name = name; }
Any ideas? Same issue known?
UPDATE
Changed code to this, based on comments, still same issue
private:
int id;
QString name;
public;
int getId() { return id; } // OK
void setId(int setTo) { id = setTo; }
QString getName() { return name; } // SIGSEGV
void setName(QString setTo) { name = setTo; }
I was facing similar issue. Although I could not find the root cause of this issue, I have another observation.
If we define the getter functions outside the class declaration using scope resolution operator the code works.
QString MyClass::GetX(void) {
return mX;
}
QString MyClass::GetY(void) {
return mY;
}
class MyClass
{
public:
MyClass(){}
/* Functions for setting mX and mY strings. */
QString GetX(void);
QString GetY(void);
isDataAvailable()
{
return mAvailable;
}
private:
bool mAvailable;
QString mX;
QString mY;
};
As I understand, in C++, if we define a function within class declaration, by default it is inline... so the issue could be something related with inlining of the functions.
thinking further about the way objects are created in memory, I thought that a QString maybe doesn't reserve fixed number of bytes, which could be the cause of this strange behavior and guess what, a dummy change solved my problem...
This feels like a really "dirty" solution, but at least I can go on with my work ;-)
But any idea's on the root cause would really be appreciated! Thanks already for all the valuable comments!!!
private:
QString name; // FIRST DEFINE QSTRING
int id; // THEN DEFINE INT
public;
int getId() { return id; } // OK
void setId(int setTo) { id = setTo; }
QString getName() { return name; } // OK
void setName(QString setTo) { name = setTo; }
I created a singleton class
class AreaDataRepository {
private:
AreaDataRepository();
AreaDataRepository(const AreaDataRepository& orig);
virtual ~AreaDataRepository();
Way onGoingWay;
public:
static AreaDataRepository& Instance()
{
static AreaDataRepository singleton;
return singleton;
}
void SetOnGoingWay(Way onGoingWay);
Way const & GetOnGoingWay() const;
};
void AreaDataRepository::SetOnGoingWay(Way onGoingWay) {
this->onGoingWay = onGoingWay;
}
Way const & AreaDataRepository::GetOnGoingWay() const {
return onGoingWay;
}
header file of Way
class Way {
private:
std::string id;
std::string name;
public:
Way();
Way(const Way& orig);
virtual ~Way();
void SetName(std::string name);
std::string const & GetName() const;
void SetId(std::string id);
std::string const & GetId() const;
};
Then i'm created a Way object and set vales of id and name.
Way wayNode;
wayNode.SetId("123");
wayNode.SetName("jan")
AreaDataRepository::Instance().SetOnGoingWay(wayNode);
After assign OngoingWay accessing it from another class.
std::cout << AreaDataRepository::Instance().GetOnGoingWay().GetId();
the vale is not printing.
I'm going psychic here.... and I divine that your implementation of SetId is like this:
void SetId(std::string id) { id = id; }
that does not set the member variable, that sets the parameter to itself. And since your constructor most likely set the member variable id to "" you're printing empty strings. Either change the name of the parameter (to newId for example) to avoid the conflict or change the implementation to:
void SetId(std::string id) { this->id = id; }
As proof of this claim here's the result for the first version, as you see it prints nothing. And here is the result for the second, as you can see it prints the number.
The problem boils down to this: you have function parameter names that are the same as the name of your member variables and the function parameters are shadowing/hiding the member variables.
The only place this cannot happen is in a constructor's initialization list:
class Foo {
int x;
public:
Foo(int x): x(x) {} // <-- this works
void SetX(int x) { x = x; } // <-- this won't the parameter is hiding the member variable
};
Demo for the above snippet
std::cout is buffered in most implementations, if not in all. That means, the stream will wait for you to end a line before writing out any data. So, you can easily fix this by changing your output statement to
std::cout << AreaDataRepository::Instance().GetOnGoingWay().GetId() << std::endl;
A typical getter/setter looks like this:
void setName(const std::string& _name) { name = _name; }
std::string getName() const { return name; }
How can I do the same if the member is a function pointer like this:
void setBotFunc(int(*botFunc)()) { botFunction = botFunc; }
int (*getBotFunc() const)() { return botFunction; }
Particularly I don't know how to declare the setter in a way that says 'I will only read and not modify the pointer (value)'. Does this even make sense? const int (*botFunct)() is obviously treated like a function which returns a const int.
void setBotFunc( int(* const botFunc)() )
{
botFunction = botFunc;
}
How to Define or Implement C# Property in ISO C++ ?
Assume following C# code :
int _id;
int ID
{
get { return _id; }
set { _id = value; }
}
I know C# convert the get and set lines to getXXX and setXXX methods in compile time. in C++ , programmers usually define these two function manually like :
int _id;
int getID() { return _id; }
void setID(int newID) { _id = newID; }
but, I want to have the C# syntax or a stuff like it in order to have a simple usability.
In C#, we can use properties like :
ID = 10; // calling set function
int CurrentID = ID; // calling get function
In C++, we can use our function like :
setID(10); // calling set function
int CurrentID = getID(); // calling get function
Now tell me how can I implement the C# properties in ISO C++.
thanks.
As Alexandre C. has already stated, it's very awkward and not really worth it, but to give an example of how you might do it.
template <typename TClass, typename TProperty>
class Property
{
private:
void (TClass::*m_fp_set)(TProperty value);
TProperty (TClass::*m_fp_get)();
TClass * m_class;
inline TProperty Get(void)
{
return (m_class->*m_fp_get)();
}
inline void Set(TProperty value)
{
(m_class->*m_fp_set)(value);
}
public:
Property()
{
m_class = NULL;
m_fp_set = NULL;
m_fp_set = NULL;
}
void Init(TClass* p_class, TProperty (TClass::*p_fp_get)(void), void (TClass::*p_fp_set)(TProperty))
{
m_class = p_class;
m_fp_set = p_fp_set;
m_fp_get = p_fp_get;
}
inline operator TProperty(void)
{
return this->Get();
}
inline TProperty operator=(TProperty value)
{
this->Set(value);
}
};
In your class where you wish to use it, you create a new field for the property, and you must call Init to pass your get/set methods to the property. (pref in .ctor).
class MyClass {
private:
int _id;
int getID() { return _id; }
void setID(int newID) { _id = newID; }
public:
Property<MyClass, int> Id;
MyClass() {
Id.Init(this, &MyClass::getID, &MyClass::setID);
}
};
Short answer: you can't.
Long answer: You could try to simulate them via proxy classes, but believe me this is not worth the minor incovenience in having set/get functions.
You'd have basically to define a class which forwards all the behavior of the variable. This is insanely hard to get right, and impossible to be made generic.
Quite simply. I'd argue this even has no overhead compared to making the variable public. However, you can't modify this any further. Unless, of course, you add two more template parameters that are call backs to functions to call when getting and setting.
template<typename TNDataType>
class CProperty
{
public:
typedef TNDataType TDDataType;
private:
TDDataType m_Value;
public:
inline TDDataType& operator=(const TDDataType& Value)
{
m_Value = Value;
return *this;
}
inline operator TDDataType&()
{
return m_Value;
}
};
EDIT: Don't make the call back functions template parameters, just data members that are constant and must be initialized in the constructor for the property. This inherently has greater overhead than simply writing a get and set method your self, because you're making function calls inside of your gets and sets this way. The callbacks will be set at run-time, not compile-time.