Im studying programming and I just started learning about set and get functions.
My questions is if it is common practise to use set-functions with a return value?
Like when the set-function performs validation i would like it to return true if the incoming value passes the validation.
Googled it and looked throug my course material and found nothing, only void set-functions everywhere!! :)
Thx
In some cases you may want to return the reference to *this from setter methods to implement fluent interface. A simple example:
class C {
int x,y;
public:
C& setX(int value) { x = value; return *this; }
C& setY(int value) { y = value; return *this; }
};
such class may be then used in the following way:
C c;
c.setX(1).setY(2);
The core motivation for getter/setter is value validation / sanity check values so returning a bool is a common way to make known if operation occurred successfully:
bool Class::setSomething(int a)
{
if (is_ok(a))
{
// set...
return true;
}
return false;
}
This is
quick/easy to implement
has smaller footprint than exception handling (although this is negligible these days)
but
it can't pass back any extra information to the caller (why did it break?)
is easier to ignore compared to exceptions
Depending on what the setter is doing.
My set functions which only assign values to class members are void
void Class::setParameter(Parameter param)
{
m_parameter = param;
}
if the setter is doing more than this, I can envisage returning a boolean.
Related
I am working with a large code base, and there are a number of publicly defined variables. Unfortunately, the functions of accessing these variables has changed, and this new functionality would be best encapsulated by public accessors and a private instance variable.
So, I am trying to make this change. To do so, I planned to make each public property private and then create accessors. But, I don't want to change any of the code which accesses the old public properties. For example:
After changing the public property to private, I have the following class:
class Test {
private:
int item = 5;
public:
int GetItem() {
return item;
};
void SetItem(int new_item) {
item = new_item;
};
};
In the past, "item" used to be a public property of the class, and it was accessed through:
Test* t = new Test();
int item = t->item;
Now though, I need to add new functionality to the way in which "item" is retrieved. For example:
int GetItem() {
// Some complicated code which changes "item"
return item;
};
How can I keep the same syntax:
int item = t->item;
But have this actually perform:
int item = t->GetItem();
Any help is greatly appreciated!
You can make int item = t.item; work, by defining item as a member variable whose type is a helper class with a custom conversion operator int() defined. Also, operator=(int new_value) to intercept the set operation.
What you can't make work is
int& item = t.item;
or
int* pitem = &t.item;
because both of these enable direct memory access, without going through any getter or setter. When creating the reference or pointer, you can't even determine how many accesses there will be or whether they will be reads or writes.
C++ is a compiled non-reflective language, i.e. you can't just "look names up as you access an element", because in the binary, there are no names anymore.
So, no, what you want is impossible. (at least not without restrictions – see Ben Voigt's excellent answer; having a "transparent" property which is in fact a getter call surely isn't worth the pitfalls you're building with that-)
Also, please don't let your C++ become Java just for the sake of having getters and setters – if they don't actually add security, I don't really see the point of using them
In case that your question is based in the fact that you don't want to call 2 different functions for setting and getting, you can make a function that returns a reference of the member:
int& Item()
{
// Some complicated code which changes *items
return item;
}
as you can see, the return type is int& instead of int. so you can use this function this way
t.Item() = someValue;
To expand on Ben Voight's answer, you can define a proxy template that allows this without the boiler plate:
template <typename Return, typename Containing, Return (Containing::* func)()>
struct proxy
{
Containing& c;
proxy(Containing& c) : c(c) {}
operator Return() { return (c.*func)(); }
Return& operator=(const Return& r) { return (c.*set)() = r; }
};
Then to define a "property"
class c {
int y_;
int get_y() { std::cout << "Getting y" << std::endl; return y_; }
public:
proxy<int, x, &x::get_y> y;
c() : y(*this) {}
};
And in client code
int main() {
c val;
val.y = 5;
std::cout << val.y << std::endl;
}
I am going over a mock exam in revision for my test, and one question on the paper confuses me.
Q.)An application is required to pass a structure to a function, which will modify the contents of the structure such that on return from the function call the caller can use the new structure values. Would you pass the structure to the function by value, address or reference?
State clearly why you chose a particular method. Justify your choice by comparing the three methods.
Now I have difficulty understanding this, because I assume the best answer to the question would always be by Ref as that takes the reference pointer of the value and edits its contents rather than just getting a copy. This would be different if using a class based program.
The only other method I would understand would be having a separate value and getting and setting the values, but this would mean extra lines of code, I am a little unsure on what this means, can anyone help enlighten me ? I do not know any other methods to achieve this.
This is not "advanced programming"; it is the absolute basics of C++.
Whether return-by-value or "out" parameters (implementing using references or pointers) are "best" for any given use case depends on a number of factors, style and opinion being but two of them.
// Return by value
// T a; a = foo(a);
T foo(const T& in) // or: T foo(T in)
{ // {
T out = in; //
out.x = y; // in.x = y;
return out; // return in;
} // }
// Out parameter (reference)
// T a; foo(a);
void bar(T& in)
{
in.x = y;
}
// Out parameter (pointer)
// T a; foo(&a);
void baz(T* in)
{
in->x = y;
}
The question is asking you what the pros and cons are of these three approaches.
I like the feature in Python that can return None when it doesn't find the correct return value. For example:
def get(self, key):
if key in self.db:
return self.db[key]
return None
I need to implement the same feature in C++. I think about some possibilities.
Return true/false, when true get the value from reference or pointer
bool get(string key, int& result)
{
if (in(key, db)) {
result = db[key];
return true;
}
return false;
}
Throw an error for notifying None case
int get(string key) throw (int)
{
if (in(key, db)) {
result = db[key];
return result;
}
throw 0;
}
try {
....
}
catch (int n)
{
cout << "None";
}
Use pair
pair<bool, int> getp(int i)
{
if (...) {
return pair<bool, int>(true, 10);
}
return pair<bool,int>(false, 20);
}
pair<bool, int> res = getp(10);
if (res.first) {
cout << res.second;
}
Which one is normally used in C++? Are there any other ways to do it in C++?
The normal C++ way to do this (note: C++ is not Python) is to return iterators from such functions and return end() when the item can't be found.
If you wish to use non-iterator return values however, use boost::optional and return boost::none when you would return Python's None.
Definitely don't use throw unless you expect to never have the error case during normal execution.
I achieved the good/bad return value using a small custom Checked templated class.
My actual class was a little more comprehensive, including assignment operators, error reason strings and specialisations for reference types, et cetera, which is why I didn't use boost::optional<T>. I could publish the full class if there is interest.
The general gist of the class is this:
static const class Bad {} None;
template<typename ValueType>
class Checked
{
public:
// Constructor for good value.
Checked(ValueType x)
: value(x), valid(true)
{}
// Constructor for bad value.
Checked(Bad)
: value(), valid(false)
{}
operator ValueType(void) const
{
if (!valid)
;//assert or throw...
return value;
}
ValueType value;
bool valid;
};
This can be used like so:
Checked<int> Divide(int numerator, int denominator)
{
if (denominator == 0)
return Bad(); // or None;
return numerator / denominator; // Automatically uses the "good value" constructor
}
or:
Checked<int> result = Divide(4, 5);
if (result.valid)
std::cout << result; // or result.value
else
std::cout << "Bad!";
This approach is often more efficient than the reference approach because of return value optimisation.
I think different projects in C++ use different standards, but Return true/false you mentioned could be the most common way in C++, although some people prefer to return false on success while the others return true on success. In other cases, if the value you would like to get is a pointer, then returning null is another common way in C++.
For example, if you're working on Microsoft related projects, then the most common way is to return HRESULT, which is a return type introduced by Microsoft.
In linux, functions usually return 0 on success, and non-zero value indicates error code.
(you may find this discussion helpful).
I would say that those three methods are all very common in C++.
It goes without saying that if the return type already can have some sort of "invalid" or "zombie" state (e.g., like a NULL pointer or a NaN number), then that might just be the easiest thing to use.
The "take output-parameter by reference and return an error-code" is the more traditional C-style way of doing things, which is, of course, very common. The tradition is to return 0 on success and some error-code on failure (any non-zero value).
The "throw an exception if you can't return a value" generally makes sense if you adopt exceptions in your code. This is very common, but not universally accepted (not everyone likes or uses exceptions for the same purposes).
Those first two options are in a never-ending feud (i.e., error-codes vs. exceptions), and it really depends on which side you pick. So, I would refer you to that debate (which is too subjective for StackOverflow, of course).
The "return a pair of bool and value" is, I would say, less common, but still I've seen this many times. With the adoption of tuples (boost::tuple or std::tuple (C++11)) and with the use of tiers (boost::tie or std::tie (C++11)), the whole idea of returning multiple values from a function (like many languages allow) is ever more attractive and used in practice.
Among other options, you have boost::optional<T>, whose name is pretty self-explanatory (basically, the third option (pair) wrapped in a prettier package). And you might also have Alexandrescu's Expected template, which gives you a hybrid of all three options such that you get a return value bundled with a flag to know if it is valid or not, and bundled with an exception describing why it couldn't produce the value, which would be automatically thrown if you attempt to read the invalid value. However, the template requires C++11 features to work.
When returning pointer, I can use reinterpret_cast for NULL return.
class A
{
};
A* a(int i)
{
if (i == 0) return new A();
return reinterpret_cast<A*>(NULL);
}
int main(int argc, char *argv[]) {
A* result = a(1); // result is NULL
if (result == NULL) {
cout << "NULL returned";
}
result = a(0);
if (result != NULL) {
cout << "NON NULL returned";
}
}
This discussion is about a name of default value:
C#: Should the default value of an enum be None or Unknown?
However, large amount of people I spoken with recently considered default enum values harmful, unnecessary and potentially leading to a bad practice.
As an example consider the following:
enum eJobStates
{
JOB_STATE_INITIALISING,
JOB_STATE_PROCESSING,
JOB_STATE_DONE
};
It would not make sense for a job to be in say, JOB_STATE_UNKNOWN, but you can imagine that any structure that might be used for monitoring of said jobs could use such value.
Are there any best practices / rules of thumb concerning creating a default value when defining an enum? Should they be avoided at all cost whenever possible?
An invalid default value is basically a variant in your design. The object isn't valid when it's created. You should avoid that when it's reasonable. By no means should you avoid it "at all costs."
Some problems require you to start in a variant state. In that case, you have to reason about that invalid value mentally. If you avoid naming it you are actively making your code less expressive. Think about it in terms of communication between you and the person that will have to maintain the code later.
Dealing with it downwind is annoying. You start in a variant state, but by the time it's relevant you hope that it is no longer variant. The strategy I prefer is allow users to ignore the variant state and just throw when I've made a mistake.
namespace FooType {
enum EnumValue {
INVALID = 0
,valid
};
}
struct Foo {
Foo() : val(FooType::INVALID) {}
FooType::EnumValue get() const {
if (val == FooType::INVALID)
throw std::logic_error("variant Foo state");
return val;
}
FooType::EnumValue val;
};
This frees your users from having to reason about your variance, which is worth fighting for.
If you can't get away with that, I usually prefer to degrade to safe and unsafe interfaces.
struct Foo {
Foo() : val(FooType::INVALID) {}
bool get(FooType::EnumValue& val_) const {
if (val == FooType::INVALID)
return false;
val_ = val;
return true;
}
FooType::EnumValue get() const {
FooType::EnumValue val_;
if (!get(val_))
throw std::logic_error("variant Foo state");
return val_;
}
FooType::EnumValue get_or_default(FooType::EnumValue def) const {
FooType::EnumValue val_;
if (!get(val_))
return def;
return val_;
}
FooType::EnumValue val;
};
These sorts of interfaces are good for things like databases, where null values may be expected.
I have a C++ struct and a method:
struct Account
{
unsigned int id;
string username;
...
};
Account GetAccountById(unsigned int id) const { }
I can return an Account struct if the account exists, but what to do if there's no account?
I thought of having:
An "is valid" flag on the struct (so an empty one can be returned, with that set to false)
An additional "is valid" pointer (const string &id, int *is_ok) that's set if the output is valid
Returning an Account* instead, and returning either a pointer to a struct, or NULL if it doesn't exist?
Is there a best way of doing this?
You forgot the most obvious one, in C++:
bool GetAccountById(unsigned int id, Account& account);
Return true and fill in the provided reference if the account exists, else return false.
It might also be convenient to use the fact that pointers can be null, and having:
bool GetAccountById(unsigned int id, Account* account);
That could be defined to return true if the account id exists, but only (of course) to fill in the provided account if the pointer is non-null. Sometimes it's handy to be able to test for existance, and this saves having to have a dedicated method for only that purpose.
It's a matter of taste what you prefer having.
From the options given I would return Account*. But returning pointer may have some bad side effect on the interface.
Another possibility is to throw an exception when there is no such account. You may also try boost::optional.
You could also try the null object pattern.
It depends how likely you think the non-existent account is going to be.
If it is truly exceptional - deep in the bowels of the internals of the banking system where the data is supposed to be valid - then maybe throw an exception.
If it is in a user-interface level, validating the data, then probably you don't throw an exception.
Returning a pointer means someone has to deallocate the allocated memory - that's messier.
Can you use an 'marker ID' (such as 0) to indicate 'invalid account'?
I would use Account* and add a documentation comment to the method stating that the return value can be NULL.
There are several methods.
1) Throw an exception. This is useful if you want GetAccountById to return the account by value and the use of exceptions fit your programming model. Some will tell you that exceptions are "meant" to be used only in exceptional circumstances. Things like "out of memory" or "computer on fire." This is highly debatable, and for every programmer you find who says exceptions are not for flow control you'll find another (myself included) who says that exceptions can be used for flow control. You need to think about this and decide for yourself.
Account GetAccountById(unsigned int id) const
{
if( account_not_found )
throw std::runtime_error("account not found");
}
2) Don't return and Account by value. Instead, return by pointer (preferably smart pointer), and return NULL when you didn't find the account:
boost::shared_ptr<Account> GetAccountById(unsigned int id) const
{
if( account_not_found )
return NULL;
}
3) Return an object that has a 'presence' flag indicating whether or not the data item is present. Boost.Optional is an example of such a device, but in case you can't use Boost here is a templated object that has a bool member that is true when the data item is present, and is false when it is not. The data item itself is stored in the value_ member. It must be default constructible.
template<class Value>
struct PresenceValue
{
PresenceValue() : present_(false) {};
PresenceValue(const Value& val) : present_(true), value_(val) {};
PresenceValue(const PresenceValue<Value>& that) : present_(that.present_), value_(that.value_) {};
explicit PresenceValue(Value val) : present_(true), value_(val) {};
template<class Conv> explicit PresenceValue(const Conv& conv) : present_(true), value_(static_cast<Value>(conv)) {};
PresenceValue<Value>& operator=(const PresenceValue<Value>& that) { present_ = that.present_; value_ = that.value_; return * this; }
template<class Compare> bool operator==(Compare rhs) const
{
if( !present_ )
return false;
return rhs == value_;
}
template<class Compare> bool operator==(const Compare* rhs) const
{
if( !present_ )
return false;
return rhs == value_;
}
template<class Compare> bool operator!=(Compare rhs) const { return !operator==(rhs); }
template<class Compare> bool operator!=(const Compare* rhs) const { return !operator==(rhs); }
bool operator==(const Value& rhs) const { return present_ && value_ == rhs; }
operator bool() const { return present_ && static_cast<bool>(value_); }
operator Value () const;
void Reset() { value_ = Value(); present_ = false; }
bool present_;
Value value_;
};
For simplicity, I would create a typedef for Account:
typedef PresenceValue<Account> p_account;
...and then return this from your function:
p_account GetAccountByIf(...)
{
if( account_found )
return p_account(the_account); // this will set 'present_' to true and 'value_' to the account
else
return p_account(); // this will set 'present_' to false
}
Using this is straightforward:
p_account acct = FindAccountById(some_id);
if( acct.present_ )
{
// magic happens when you found the account
}
Another way besides returning a reference is to return a pointer. If the account exists, return its pointer. Else, return NULL.
There is yet another way similar to the "is valid" pattern. I am developing an application right now that has a lot of such stuff in it. But my IDs can never be less than 1 (they are all SERIAL fields in a PostgreSQL database) so I just have a default constructor for each structure (or class in my case) that initializes id with -1 and isValid() method that returns true if id is not equal to -1. Works perfectly for me.
I would do:
class Bank
{
public:
class Account {};
class AccountRef
{
public:
AccountRef(): m_account(NULL) {}
AccountRef(Account const& acc) m_account(&acc) {}
bool isValid() const { return m_account != NULL);}
Account const& operator*() { return *m_account; }
operator bool() { return isValid(); }
private:
Account const* m_account;
};
Account const& GetAccountById(unsigned int id) const
{
if (id < m_accounts.size())
{ return m_accounts[id];
}
throw std::outofrangeexception("Invalid account ID");
}
AccountRef FindAccountById(unsigned int id) const
{
if (id < m_accounts.size())
{ return AccountRef(m_accounts[id]);
}
return AccountRef();
}
private:
std::vector<Account> m_accounts;
};
A method called get should always return (IMHO) the object asked for. If it does not exist then that is an exception. If there is the possibility that something may not exists then you should also provide a find method that can determine if the object exists so that a user can test it.
int main()
{
Bank Chase;
// Get a reference
// As the bank ultimately ownes the account.
// You just want to manipulate it.
Account const& account = Chase.getAccountById(1234);
// If there is the possibility the account does not exist then use find()
AccountRef ref = Chase.FindAccountById(12345);
if ( !ref )
{ // Report error
return 1;
}
Account const& anotherAccount = *ref;
}
Now I could have used a pointer instead of going to the effort of creating AccountRef. The problem with that is that pointers do not have ownership symantics and thus there is no true indication of who should own (and therefore delete) the pointer.
As a result I like to wrap pointers in some container that allows the user to manipulate the object only as I want them too. In this case the AccountRef does not expose the pointer so there is no opportunity for the user of AccountRef to actually try and delete the account.
Here you can check if AccountRef is valid and extract a reference to an account (assuming it is valid). Because the object contains only a pointer the compiler is liable to optimize this to the point that this is no more expensive than passing the pointer around. The benefit is that the user can not accidentally abuse what I have given them.
Summary: AccountRef has no real run-time cost. Yet provides type safety (as it hides the use of pointer).
I like to do a combination of what you suggest with the Valid flag and what someone else suggested with the null object pattern.
I have a base class called Status that I inherit from on objects that I want to use as return values. I'll leave most of it out of this discussion since it's a little more involved but it looks something like this
class Status
{
public:
Status(bool isOK=true) : mIsOK(isOK)
operator bool() {return mIsOK;}
private
bool mIsOK
};
now you'd have
class Account : public Status
{
public:
Account() : Status(false)
Account(/*other parameters to initialize an account*/) : ...
...
};
Now if you create an account with no parameters:
Account A;
It's invalid. But if you create an account with data
Account A(id, name, ...);
It's valid.
You test for the validity with the operator bool.
Account A=GetAccountByID(id);
if (!A)
{
//whoa there! that's an invalid account!
}
I do this a lot when I'm working with math-types. For example, I don't want to have to write a function that looks like this
bool Matrix_Multiply(a,b,c);
where a, b, and c are matrices. I'd much rather write
c=a*b;
with operator overloading. But there are cases where a and b can't be multiplied so it's not always valid. So they just return an invalid c if it doesn't work, and I can do
c=a*b;
if (!c) //handle the problem.
boost::optional is probably the best you can do in a language so broken it doesn't have native variants.