Pre-made instances of a class - c++

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?

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;

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.

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.

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

Related

const object or private/const data members (variables) in C++?

We know that const object members cannot be modified once declared but what is the real use of them? We can individually declare variables to be const inside the class or declare them private.
If there is any other significance of const object in C++, then please mention that too.
To answer your question literally:
If you make members of a class const, that applies to every instance of the class, but only to the members that you made const.
If you make an object const, that applies to a single instance of that class, but it does apply to all members of that instance.
const is one of the most elementary subjects in C++, in my opinion. Something that is way too often overlooked.
Generally const has three use cases:
Allowing the compiler to optimize more aggressively
Allowing the compiler to point out our mistakes when we accidentally try to change a const value
Convey intend by specifying that we do not want an object changed
In the case of a const member of a class, we force the object to be initialized during instantiation of the class. Preventing us from accidentally changing it's value in member functions. Which is the big difference to just using a private member variable. We still can accidentally change a private member variable anywhere inside the class.
One of the most useful ways to use const is with parameters:
This can allow major optimization for the compiler, for various reasons that are out of scope of this answer.
And in the case of const references, the compiler can prevent you from accidentally changing the value of that reference.
Most importantly, it allows you to define the signature of your function in a more clarifying way.
I luckily use this once(so far). And i never thought i would need to use a const in a member variable.
class TypeA {
protected:
DataX const* m_data; //get a pointer to a data that shouldn't be modified even inside the class.
public:
TypeA(DataX const* p){
m_data = p;
}
auto& getData(){ return *m_data; } //will return DataX const&
}
For the private member variables, i think they are best for helper-variables in the current class that are really not part of the object logically. Maybe for caching, temporary holder of some data that should be there for a time duration, a counter for an algorithm, etc. And they are only used and should be used in the current class. You don't want other programmers to use them in the derived class because they have a very special use so you hide them in private.
Another example for const member are for constant values aside for enums. I prefer enum over a variable that takes storage but some programmer prefer following on what they used to however you convinced them not to(maybe i'm wrong, and they are really correct, and maybe in the future for some reason the const in the language changed, and then using const might be better.)
class TypeA {
public:
const int HEY_VALUE = 101;
const int YOH_VALUE = 102;
const int HELP_VALUE = 911;
const float MIN_SOMETHING = 0.01;
static const int HELLO_EARTH = 10;
//...
}
I can't find this specific code of mine, but i think i used & instead of const*. I used it like this.
class TypeA {
protected:
DataX& m_data;
public:
TypeA(DataX& p):m_data(p){ //you can only set this once in the constructor
}
auto& getData(){ return m_data; } //will return DataX const&
}
I really prefer using . instead of -> for personal reasons so I really pushing myself to achieve the syntax i want and i came with these weird solutions. It's fun because I discovered that those weird approaches are still valid and achievable in c++.
Update
If there is any other significance of const object in C++, then please mention that too.
Maybe you can const some filler bytes on specific part of the class.
class TypeA {
protected:
const int HEADER_BYTES = 0x00616263;
int m_data1;
int m_data2;
const uint8_t ANOTHER_FILLER_FOR_SOME_REASON = 0xffffffff; //maybe forcing offset address, or alignment, etc.
int m_anotherData;
}
Generally, const keyword is being used to improve readability of the code you are writing.
However, in some cases const can also allow compiler optimizations. Let's see the following code snippet:
int const i = 1;
fun(&i);
printf("%d\n", i);
Here, trying to modify the variable i would cause an Undefined Behaviour. Therefore, the compiler will assume modification won't be even tried so it will pass the value 1 to the printf function.
Same is valid for const data members.

Argument passing standardization

My C++ project is getting huge. In some situations I'm passing arguments by reference just for my own convenience, in some I don't. Here's an example:
struct foo{
foo(int &member){
this->member = &member;
}
private:
int *member;
};
I'm using this pattern when I don't want to create two instances of the int variable. I don't have to implement the get or modify methods to manipulate its value. Instead I can change the variable without even accessing the foo object. However sometimes I'm using a different way of managing the member variables:
struct foo{
foo(int member){
this->member = member;
}
void modify_member(){
this->member = 6;
}
int get_member(){
return this->member;
}
private:
int member;
};
I'm not sure whether mixing these two methods of managing members in the same struct is a good practice. Should I normalize it? So for example EVERY function in the given struct will be using the "pass by value" method?
Your first case is a recipe for disaster. You'll end up with dangling pointers and a truck load of undefined behaviour.
Your second case is a poor attempt at encapsulation. There's no need for it. Just use the int. That will reduce the size of your code base.
Code should be simple to read and simple to change, that is in a way that does not break your program. Example one will lead to code, where you can hardly tell where foo instances are altered. Not to forget all the others issues mentioned already.
Example two is okay. In general, providing getters and setters let you add constraints later such as checking value ranges. So I recommend using them, unless you have good reasons not to do so. It also makes refactoring easier.
When passing parameters in a function: As a rule of thumb use pass by value in case of primitive types: int, double, etc.. When passing objects use constant References foo(const MyClass &myClass).
class MyClass {
public:
MyClass(const MyOtherClass &member1, int member2){
this->member1 = member1;
this->member1 = member1;
}
// other functions, getters, setters omitted...
private:
MyOtherClass member1;
int member2;
};

How to use common values in many objects in C++?

I need to instantiate many objects from a class, but each one of them needs to be aware of a certain value X that is common for every object of this class, like a global parameter. This is necessary for my constructors to work properly in my objects.
Is there a way to do that without passing the value as a constructor parameter? What I wanna do is use the same variable in all objects so I don't waste RAM.
*in my real situation it's not just an X value, is a 1024-dimmension int vector.
What you want is a static member. "When a data member is declared as static, only one copy of the data is maintained for all objects of the class". e.g.
class myClass {
public:
static int x;
};
I assume you mean that you want a vector of size 1024 as the shared variable across all your classes. You could do this:
class MyClass {
static std::vector<int> s_my_vector;
}
This code would go into your header file. In your cpp file, you'd have to initialize the std::vector. However, I do not recommend this. Class static variables that require constructor calls (i.e. not primitives or POD types) have a lot of gotchas that I'm not planning to go into. I will offer a better solution however:
class MyClass {
static std::vector<int> & GetMyVector()
{
static std::vector<int> my_vector;
static bool initialized = MyVectorInit(my_vector);
return my_vector;
}
static bool MyVectorInit(std::vector<int> & v)
{
v.resize(1024);
...
}
public:
MyClass() {
std::vector<int> & v = GetMyVector();
...
}
static void EarlyVectorInit()
{
GetMyVector();
}
}
In this case, the static local variable ensures that there will only be one copy of my_vector, and you can get a reference to it by calling GetMyVector. Furthermore, the static bool initialized is guaranteed to only be created once, which means that MyVectorInit will only be called once. You can use this method in case you need to populate your vector in some non-trivial way that can't be done in the constructor.
The way I've written it, your vector will be created automatically the first time you need to use it, which is fairly convenient. If you want to manually trigger creation for some reason, call EarlyVectorInit().

Defining const static that needs setting up at runtime

I'm making use of a class with a few utilities defined as static methods eg.
QDate SSIMUtils::ConvertSSIMDate(QString s) {
QDate rtnDt;
//...conversion code
return rtnDt;
}
I would like to define a few constants in this class eg. LOW_DATE and was thinking of putting in something like
const static QDate LOW_DATE; // Need to set this somewhere to 1/1/1970
Unfortunately, I can't define it pre-compile time like I would say an int eg.
const static int SSIMUtils::myI = 4;
because it requires the use of a setDate method.
My question is how should I define a static const that I need to set up codewise, as the constant requires initialisation. I'd been thinking of defining it in the .h file eg.
const static QDate LOW_DATE;
then in the .cpp file, at the top, doing something like
SSIMUtils::LOW_DATE.setDate(1970,1,1);
But this is syntactically incorrect. What I'd ultimately like to do is use this constant in other classes eg.
if (myQDate.compare(SSIMUtils::LOW_DATE)==0) {
// do something.
}
What's the right way to set up a constant value in a static class that you need to adjust at run time ie. like a constructor?
As I mentioned in a comment, QDate has a constructor equivalent to setDate(), which allows for initialisation of a 'const' object.
You must declare your static constant the following way:
myclass.h:
#include <QDate>
class myclass {
public:
const static QDate CONST_DATE;
};
myclass.cpp:
#include "myclass.h"
const QDate myclass::CONST_DATE(1970, 1, 1);
I tested this using a std::string instead of a QDate (no QT available right now), and it works just as you want.
It depends on where the necessary information for the
initialization comes, or rather, when it is available. If it's
always available, and the type supports copy, then you can
just write a function which returns the initialized type:
namespace {
MyType getInitialized()
{
MyType results;
// ...
return results;
}
}
static MyType const lowDate( getInitialized() );
If it doesn't support copy, you can derive from it, providing
a specialized constructor:
class MyTypeInitialized : public MyType
{
public:
MyTypeInitialized()
{
// ...
}
};
MyTypeInitialized lowDate;
This has the disadvantage of masking the true type from the
client code, but otherwise works well.
If the information isn't available until later; e.g. it depends
on command line arguments, then you may have to use a variant of
the singleton idiom, where you have two instance functions:
one of which takes the necessary arguments for initialization,
and must be called first. (Or that may even be overkill; it
might be sufficient to have a global std::unique_ptr<MyType
const> lowDate;, and initialize that with an object newed at
the start of main. The main different is in the client
syntax.)
You cannot change something declared constant at run-time, by definition.
The closest you can get to run-time constant initialization is to initialize in a class'
constructor initializer list:
SomeClass(int constantValue) :
myConstant(constantValue)
{
...
}
Given that you are building a static class, you are probably not constructing an object though. You can always resort to having a setter method which only allows setting the value once (in which case you can not declare the field const, obviously).
As the name implies, it is a constant, it cannot (should not) be changed once initialised. The only place that you can assign a value to a constant member variable is in the constructor (that is, without weird const_casts).
Your QDate may be trivial to construct -- using a static constant may not be better than creating a new date for that constant each time the function is called.
In the interest of answering the question, let's assume it is complex to construct and that a static constant is best idea. You can simply write:
QDate SSIMUtils::ConvertSSIMDate(QString s) {
static const QDate LOW_DATE( /* ...construct it... */ );
QDate rtnDt;
//...conversion code
return rtnDt;
}
Note: Looks like SirDarius explained how you can construct this type directly, without an intermediate (+1), although a function-local static constant is generally much better than a global constant because global constants lead to some very tough initialization problems in C++.
This creates a function local static which will be initialized once, and in a thread safe manner before it is read and when the function is called.
If the instance cannot be constructed easily, it helps at times to initialize using the copy constructor and then creating an accessory function:
QDate SSIMUtils::ConvertSSIMDate(QString s) {
struct F { static QDate Low() { return ...; } };
static const QDate LOW_DATE(F::Low()); // << initialize the constant using the copy ctor
QDate rtnDt;
//...conversion code
return rtnDt;
}
So the short approach using the construction provided by SirDarius using a function-local-static is:
QDate SSIMUtils::ConvertSSIMDate(QString s) {
static const QDate LOW_DATE(1970, 1, 1);
QDate rtnDt;
//...conversion code
return rtnDt;
}

static const in a struct, using constructor

I was looking for a method to initialize a static float inside a structure BUT using the constructor of the struct. In this site there are already solution to initialize the value but I was unable to find a solution that explicitly use the constructor.
The idea is the following:
struct test {
static const float a;
int b;
test(int bb, float a);
};
test::test(int bb, float aa) {
b=bb;
a=aa;
}
int main() {
int bval=2;
float aval=0.25;
struct test aaa(bval, aval);
return 0;
}
How to implement it correctly? Thank you for any advice.
You can't initialise it other than
const float test::a = something;
Outside the class (in a single compilation unit). However, you can do what you wrote and that will set the variable to the value you pass.
If you're wanting to set it only on the first time the constructor is entered, you can (but shouldn't) do something like
test::test(int bb, float aa){
static float _unused = (test::a = aa);
b=bb;
}
But that doesn't initialise it, it just assigns a value to it, and you'll still have to pass the variable to the constructor every time and nothing will be done with it (unless you give it a default value or something). That is a really terrible design though, it's probably better just to have a static function in the class to set the variable.
Static members are not associated with a particular instance, so they will only ever be initialised once. Constructors on the other hand are invoked on a per-instance basis, so it doesn't make sense to do what you're trying to do.
You can, on the other hand, assign a new value to static members in a constructor, as you're doing above, but you still have to actually initialise the static member outside the struct in the normal manner beforehand.
It's worth observing in passing that other languages (e.g. Java) have the concept of a static constructor for exactly this sort of thing - but C++ doesn't.
That said, you might find the following question interesting:
static constructors in C++? I need to initialize private static objects
You can't initialize a static const var inside constructor.
You should initialize at declaration
static const float a = 3.1416f;
Ensure you understand const keyword.
And should be integral.