Reputation: 20264
I have class like this:
class result{
public:
int a;
int b;
int c;
};
a,b,c
can be filled with any integer. However, there is some famous cases which I will use them too much like for example the zero case where (a=b=c=0) or the identity case where (a=b=c=1) and some others.
So I want an easy way to get this instances when I want one of them without creating new object and filling it manually (the real case contains much more complex that 3 integers).
What I am doing currently is like this:
class result{
public:
int a;
int b;
int c;
static result get_zero(){
return result{0,0,0};
}
static result get_idenity(){
return result{1,1,1};
}
};
and in main:
auto id=result::get_identity();
Is this a good way to achieve what I want? Is there like an idiomatic way for doing this?
Upvotes: 1
Views: 179
Reputation: 19751
If the objects can be modified after you return them, then yes, this is the correct way, since you cannot share a single object.
NRVO (http://en.cppreference.com/w/cpp/language/copy_elision) and move-semantics remove any cost associated with returning the object by value.
If you know these objects will never be changed, you can return a result const &
instead and have the object itself be a static member of your class. At that point, you don't even technically need the getter/setter, since the static members are public and already marked as const.
class result{
public:
int a;
int b;
int c;
static result const zero_result{0,0,0};
static result const & get_zero(){
return result::zero_result;
}
static result const identity_result{1,1,1};
static result const & get_idenity(){
return result::identity_result;
}
};
don't forget to allocate the memory for your static data members in a .cpp file, though:
result const result::zero_result;
result const result::identity_result;
Upvotes: 4
Reputation: 9705
Your proposal solution it's strongly compiler optimization efficiency. Actually when result::get_identity();
is called a new result
object is created and returned.
This will invoke the initialization constructor and, in the best case, the move constructor then.
Probably your compiler will optimize that with RVO.
One good approach it may be to create const static objects from your code can refer to.
For example in your class:
class Result {
// something
public:
static const Result Zero;
static const Result Identity;
};
// ... and then you can refer to it
do_something(Result::Zero);
In that way you can refer to object which will be created only once, when your program starts and avoid instantiating always a new notorious object.
Upvotes: 1
Reputation: 1
you could make a static class of your result and use that. i did this for a product i made in c# and it worked perfectly
Upvotes: -2
Reputation: 385098
Conventionally we would probably just create a static
instance that you can re-use, copy from etc.
// someFile.h
extern const result ZERO, ID;
// someFile.cpp
const result ZERO{0, 0, 0};
const result ID{1,1,1};
Alternatively, have your class own these instances as static
members and have your functions return a reference.
To be honest, though, your current approach seems perfectly performant and may be the most easy-to-use.
Upvotes: 2