Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
On our current project, we are currently having issues with the way we are handling constants. To try to sum it up, let's say we have different action types, defined as const std::string
const std::string actionTypeX = "XXX";
const std::string actionTypeY = "YYY";
...
Those action types may have different properties, which makes them trigger different behavior. This is usually implemented through an std::unordered_map, linking the action type to whatever property we need :
const std::unordered_map<std::string, int> actionFlow = {
{ actionTypeX, DB_FLOW },
{ actionTypeY, DRL_FLOW },
.... };
Those maps are usually used in one single implementation, so we put them in anonymous namespaces in the corresponding CPP file. On the opposite, the constants strings are usually used by many files and so are defined in a common constants file.
The issue we have is that we end up having the infamous static initialization order fiasco: Some maps are using common strings that are not yet initialized, generation a segmentation fault.
The known solution for this issues are:
Put all maps that depends on those constants in the same file, thus avoiding the problem of the order. But this would create a huge, ugly file which might be difficult to maintain
Put those maps within a static function returning a reference to a static map, but in my opinion it does look a bit 'hacky'
While both solutions should work, I feel they would just be a workaround for a design problem of our application.
So my question is, how should a C++ program with many constants be designed so it is easily maintainable ?
Thank you,
Regards,
How about not using std::string for constants:
constexpr auto actionTypeX = "XXX";
By using constexpr you no longer face the issues related to static intialization fiasco. You can then safely use this constants to initialize your maps.
Furthermore, you can then use std::string_view as the keys (that's assumed you only use the global constants as the keys anyway) in the maps to get some more flexibility and keep the maps lightweight.
Put those maps within a static function returning a reference to a static map, but in my opinion it does look a bit 'hacky'
I would go with this approach, but possibly encapsulate it a bit more. It seems like the std::unordered_map is an implementation detail, and all you need to expose is the access to the constants.
Library:
A little helper that hides the static initialization can be useful. You would put this in a header to include whenever you need to define constants:
// T = value, Init = functor to initialize constants
template <typename T, typename Init>
class Constants
{
static std::unordered_map<std::string, T>& constants()
{
static bool initialized = false;
static std::unordered_map<std::string, T> map;
if (!initialized) // alternative: map.empty()
Init()(map);
return map;
}
public:
static T get(const std::string& key)
{
return constants()[key];
}
};
Constant definition:
In a concrete .cpp file, you could use it as follows:
// Your function for initialization
struct ActionFlowInit
{
void operator()(std::unordered_map<std::string, int>& map) const
{
map["one"] = 1;
map["two"] = 2;
}
};
using ActionFlows = Constants<int, ActionFlowInit>;
In a real scenario, you would expose the functor in the header, but leave the implementation of its operator() to the .cpp file, in order to abstract away the actual constants.
If you don't want to settle for std::unordered_map, the signature can of course be more generic -- just pass a parameter to operator() which allows you to register a constant.
Constant usage:
Access the constants like this:
int x = ActionFlows::get("one");
It's of course possible to add more syntactic sugar, especially for the initialization. boost::list_of can be an inspiration.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
My derived class needs to provide a function that returns a std::vector& to the caller.
I could declare a static member and initialize it either in the constructor or in the 'global scope' of the CPP file. I could also declare a local static in the derived function and return it.
The first option has declaration, initialization and return functionality in three separate locations of the code, while the second option consolidates all three elements in the same place. What are the object size, performance, etc. differences between these approaches?
Edits start here after reading comments through SergeyA. I am editing the code example of PeterT, adding a sample to show that the constructor utilizes push_back. So I must admit to SergeyA that initialization does occur in the global scope and as written below, there are four separate locations where the variable s_val appears.
//ex.h
#include <vector>
using intVec = std::vector<int>;
struct ex
{
ex();
static intVec s_val;
intVec& getVal();
};
//ex.cpp
intVec ex::s_val = intVec(5);
ex::ex()
{
if (s_val.size() == 0) {
s_val.reserve(5);
s_val.push_back(1);
s_val.push_back(4);
s_val.push_back(0);
s_val.push_back(2);
s_val.push_back(3);
}
assert(s_val.size() == 5);
}
intVec& ex::getVal()
{
return s_val;
}
I want to modernize and simplify the code to use an initializer list. It sounds like returning a global static allows me to do that in a clean and efficient manner. Is this correct ?
//ex.h
#include <vector>
using intVec = std::vector<int>;
struct ex
{
intVec& getVal();
};
//ex.cpp
static intVec s_val = { 1, 4, 0, 2, 3 };
intVec& ex::getVal()
{
assert(s_val.size() == 5);
return s_val;
}
A local static will incur the cost of an initialization guard (a mutex lock) on every call to the function. This is due to C++11 guaranteeing thread-safe initialization of statics, which for local statics means access serialization.
A global static (which also includes static class members) does not incur that cost, since global static are initialized before main() runs.
You can see the initialization guards in the generated assembly:
https://godbolt.org/z/BzdzvN
When you do do this
//ex.h
#include <vector>
using intVec = std::vector<int>;
struct ex
{
static intVec s_val;
intVec& getVal();
};
//ex.cpp
intVec ex::s_val = intVec(5);
intVec& ex::getVal()
{
return s_val;
}
Then the initialization code for instantiating the vector happens before main()
But if you do
//ex.h
#include <vector>
using intVec = std::vector<int>;
struct ex
{
intVec& getVal();
};
//ex.cpp
intVec& ex::getVal()
{
static intVec s_val = intVec(5);
return s_val;
}
Then the initialization of the static variable (the constructor of std::vector being called) happens when you call the function for the first time.
This can be an issue in multi-threaded contexts where it can lead to race-conditions, but in this case you're returning a mutable reference to a static std::vector so I'm assuming that threading doesn't matter for this specific case anyway. (nvm. see Nikos answer to this question for why that's not longer a concern)
There is some misunderstanding there. If you declare a static member of the class, you can't initialize it in the constructor. You can obviously assign it in the constructor, but it will be assigned whenever a new object will be created (potentially multiple times) which probably doesn't make any sense for most applications.
If you declare a static member, you should either make it a constexpr and initialize in-place, or initialize outside of class definition. The latter exposes you to all the glory of static initialization order fiasco, unless you can guarantee a compile-time initialization for your member.
Function-local static has not issues with initialization order, and have a defined order. However, with function local static you'd pay a minuscule price of a branch (predicted) every time you call the function. For most applications, this is not even worth talking about.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I would like to ask the proper location of typedef in C++.
Version1 : typedef outside class
typedef std::pair<std::string, int> StrIntPair;
typedef std::vector<StrIntPair> StrIntPairVec;
class MyData
{
public:
MyData(){};
~MyData(){};
private:
void addInfo(const StrIntPair &info)
{
infoVec.push_back(info);
}
StrIntPair info;
StrIntPairVec infoVec;
};
Version2 : typedef inside class public
class MyData
{
public:
MyData(){};
~MyData(){};
typedef std::pair<std::string, int> StrIntPair;
typedef std::vector<StrIntPair> StrIntPairVec;
private:
void addInfo(const StrIntPair &info)
{
infoVec.push_back(info);
}
StrIntPair info;
StrIntPairVec infoVec;
};
Version3 : typedef inside class private
class MyData
{
public:
MyData(){};
~MyData(){};
private:
typedef std::pair<std::string, int> StrIntPair;
typedef std::vector<StrIntPair> StrIntPairVec;
void addInfo(const StrIntPair &info)
{
infoVec.push_back(info);
}
StrIntPair info;
StrIntPairVec infoVec;
};
Which version is the best practice?
This depends on where you use the type alias. I'd advice you to
Put them outside of the class if you use them across classes and/or functions and the meaning of the alias is not exclusively related to the class.
Define them as public class type aliases if client code outside of the class needs to access them (e.g. to initialize the object or to store an aliased return value of a member function) but the alias is related to the class. The alias then becomes a part of the class interface.
Define them as private class type aliases when you use them exclusively inside the class, e.g. some utility data structure that is annoying to type out all the time when passing it across member functions.
The compiler will only enforce scopes of aliases that are too narrow (e.g. you use a type alias defined in the private section of your class outside of that class) and won't complain if you choose an unnecessarily permissive scope (e.g. you publicly declare the alias, but use it only in the class implementation). Hence, strive to choose the narrowest scope possible, which is in line with hiding implementation details.
As a side note, you might want to consider declaring your type aliases with using StrIntPair = std::pair<std::string, int>;, see Item 9 in Effective Modern C++. This has no influence on the above, though.
The question is about logical namespace of those names. With abstract naming like StrIntPair, StrIntPairVec and MyData there are no answers. Answers come when the things have meaning.
Lets take exactly same data structures but name them NickAndId, Friends and Player.
Now the question if to put NickAndId inside Player is about if it is specific to player. Can other entities like NonPlayerCharacter or Creature also have nickname and id expressed as same pair? Possibly. Then it should be outside.
Same question should be asked about Friends. Likely the NonPlayerCharacter and Creature can have nickname and id but do not have friends? Then it makes sense to put the type inside of Player as Player::Friends.
Finally, the types that are made private are meant only for usage by implementation details. That should be used when the name makes perfect sense in algorithms used inside of class but availability of those outside is unneeded or even worse, confusing. For example NonPlayerCharacter can react with some replicas to some states whose values are also internal to that NPC. Keeping that in sorted vector Reactions makes perfect sense inside of class. Access to ReplicaInState and Reactions from outside can be confusing.
This question already has answers here:
How to initialize private static members in C++?
(18 answers)
Closed 7 years ago.
I'm new to function pointers and am getting hung up on syntax. What I'm trying to do is define, within a class, an array of functions to do string matching. The matching functions and their storing array will be static since they will be shared by all instances of the class. The functions are stored in an array so I can iterate through within match() and try different ones. Also, I'm trying to typedef the function pointer globally because similar matching functions will be used in many such classes. I've found some stuff suggesting that the signature should maybe be bool(Money::FP)(char str) but, if true, is there no way that I can define this globally (i.e. for classes other than "Money")?
The code below does not compile so please consider it as pseudocode for what I'm trying to accomplish.
Money.h:
typedef bool(*FP)(char* str);
class Money
{
private:
static FP matchers[3] = {
Money::m1,
Money::m2,
Money::m3
};
static bool m1(char* str);
static bool m2(char* str);
static bool m3(char* str);
public:
static void match(char* str);
};
It's not working because Money::m1 refers to Money type inside its declaration. Try to decouple them, eg
class Money {
private:
static FP matchers[3];
};
FP Money::matchers[3] = {
Money::m1,
Money::m2,
Money::m3
};
In any case you might consider using std::function<bool(char*)> instead that a function pointer, since you are working with C++. Performance is not an issue until you prove it to be an issue.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
In C++, which of these ways is better?
// this is class, not a struct (just means members are public by default)
struct foo {
int w, h;
private:
public:
};
Or
class foo {
private:
int w, h;
public:
int getW() { return w; }
int getH() { return h; }
};
In this case:
foo *A;
If I'm trying to get the values of w and h,
should I use A->w and A->h for the first example or A->getW() and A->getH() for the second example?
Right now I'm using the first example, but is it in any way better practice to make methods to return the private variables? Is there some advantage to one way over the other?
If this is your only concern, then there is no practical difference. If you intend to only have members that are visible to the outside via accessor methods, then they might as well be made public (or a POD.) For example:
struct SomeSortOfInformation
{
int w, h, x, y, pixelFormat, whatever;
};
If you intend to protect implementation details, or to change the behavior of accessing a variable (i.e., this is a common idiom in C#), then feel free to use accessor methods.
void setWidth(const int& w) {
if (w <= 0) this->w = 0;
else this->w = w;
}
The immediate difference is that users of the class can assign to the values of w and h in the first example, but not the second.
The difference for future code changes is that the author of the class can change the way that foo's data is stored in the second example, but not the first. For example if the class represents a rectangle, then you could switch to storing the co-ordinates of the corners, and calculate the width and height when requested.
There is no certain way that is "better". If you have a class that is defined to be a dumb data container, that users can read from and write to, and it is guaranteed that it will not in future perform any clever calculations, then you can use public data members. An example of this in the standard libraries is std::pair, which has public data members first and second. Many OOP programmers will (on principle) never define or document any such guarantee, but the designers of the C++ standard libraries do not agree with this absolute principle. In any case C++ is not designed on strict OOP principles.
If you have a class that just so happens to store values that are useful to the user, but is not guaranteed to store them as members, then you would use accessors if necessary. An example in the standard libraries is std:vector, which has functions begin() and end(). In some implementations of vector they just return the values of two private data members, in other implementations they do something else.
If possible, though, give the class the functionality that the user needs, so that they don't need public data or accessors. An example in the standard libraries is std::stack, which has a protected data member for use by derived classes, but does not give "normal" users any direct access to it. If you find yourself routinely writing accessors for most data members of most classes you write, then you should seriously consider whether your design can be improved. Accessors mean that users of your class must provide the logic to use the data member. But the main advantage of classes is the ability to keep the logic for using data in the same place that the data is defined. If users always provide the logic then you're not using that opportunity.
By the way, there are a couple of errors in your question:
this is class, not a struct
It is a struct. It is also a class type.
int getW() { return w; }
Getters should be const functions: int getW() const { return w; }
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
class test {
public:
test(int value = 0): x(value) {}
int& get(){
return x;
}
private:
int x;
};
this will allow client code to mutate the private members
this is legal in C++, but why ?
Is there any situation where you would actually need to break the class encapsulation ?
Make a member as private, means you can not access it directly. But nothing restricts you to access it indirectly via a public member. It depends on you design. You can even do this:
class test {
public:
test() : x(y) {}
int &x;
private:
int y;
};
In your class, assume you want count how many times a member is read/write. So, you can make it private then put a member function which returns a refernce to the variable:
class test {
public:
test(int value = 0): x(value), count(0) {}
int& get(){
count++;
return x;
}
private:
int x;
int count;
};
I hope this example shows how making a member as private and then putting an indirect access to it can be useful.
Ffirst of all let's consider implementing what you describe. It would be very onerous to properly do so. Your example is easy enough. But what if the reference flowed through a number of functions before it reached the function that exposed it? The compiler would have to do exceptionally complex static analysis, beyond the levels of static analysis that are reasonable to expect from compiler writers.
So even if the designers wanted to ban this, it would not have been tractable to do so. Would the designers have wanted to stop this? Very doubtful. Had they done so, how would the [] operator be implemented on a container or a string?
Is there any situation where you would actually need to
break the class encapsulation
As example of the [] operator on containers and strings shows, this feature is in fact used to support encapsulation.
Why? Because C++ mainly tries to let you do whatever you want and not get in your way; it doesn't try very hard to keep you safe. If you want a safe language, use something else. You have something like object-orientation if you want to, but if you want to break out of that, more power to you. With great power comes great responsibility.
It's worth nothing that you don't even need this to break encapsulation; you could simply reinterpret a pointer to "test" as an integer and access the private field this way.