I've been handed a legacy C++ application to patch and add some new features, and I'm having a terrible time following some of the code, as it makes fairly extensive use of globals, huge #define macros and many extremely tersely named variables/functions (3 letter functions from 2 inheritance levels up, etc...). As such, determining the source of many of the functions or variables is rater challenging.
It also uses Hungarian notation.... sometimes (m_Thingie is a member variable, but sometimes so is thingie).
Is there any way to make it so class member access without specifying this-> fails? That would let me use the compiler to effectively determine variable source.
I don't mind if it's a horrible hack, if I can turn it on for a little while when doing refactoring, and then off for any release compilation, that would be fine.
Pick an IDE with advanced colorization, Visual Studio can do it then if you're already using it you don't need to learn anything else.
Click Tools menu then click Options.
Expand Environment settings group from the list in the left and select Fonts and Colors.
Scroll down Display items in the right panel until you find C++ ... items. There you can change settings for things you need (and more):
Change settings to highlight variables and functions according to your needing. Be aware that you can change only color (background and foreground) but size is shared. Too many colors will confuse you then you may need to make some tests before you find right combination for you.
Final result may be:
In this example you can see different colors for:
Local variables.
Global functions (anything declared outside a class).
Function parameters.
Member functions (you may also set a different color for static member functions).
Fields (you may also set a different color for static class fields).
Global variables.
Macros.
Of course literals (string, characters and numbers), user types and enumerations can have their own color combination (also specialized for templates). When you're done with refactoring you can restore default settings clicking on Use Defaults.
Related
Is there a way to create generic set/get functions in C++? I have a class with a large number of attributes but no functions (ok I should probably use a struct), and really don't want to write individual set and get functions for each data member. The functions I'm thinking of would be something like 'set_member( T variable ), where T could be anything, primitive types or user defined. I imagine perhaps you could create a struct with a struct as a member, then whenever you want to access a specific member of the member struct, you refer to it by the appropriate pointer. I've tried writing something to achieve this but no luck so far.
C++ has (as far as I know) no inbuilt way to autogenerate setter/getter functions.
You might be able to work some macro-magic (with all its pitfalls), otherwise your options are slim.
I can think of following alternatives:
Some IDEs generate get, set methods automatically for the data members of class. I am not sure if it is possible for C++ IDE. But I know that Eclipse IDE for Java does it. You may check once if Eclipse IDE for C++ has this facility.
You may write a short shell script or python script for automatically generating get, set method given a text file containing names and types of variables in each line.
By default all the members of struct are public. So use struct. Or if you decide to use class, then, put all the data members in public section. If you are not doing anything other than simple set, get, then, it might be ok to do so. However, debugging will be tedious in case if you encounter issues with changes in the data members.
I'm working on a simple framework for making 2D games. It uses components and systems, which will vary from game to game.
To make it easy for other parts of the engine to loop over all possible systems and / or components, I'd like them to let themselves be known the moment one of them is included (Each has their own header file), in a way creating a list of all possible component types and system types.
I've currently solved this by having a Register struct which is put at the bottom after a system or component definition, passing that component / system pointer as an argument to the constructer of the Register struct, i.e.:
std::vector<Component*> Components
struct Register{
Register(Component* newComponent){
Components.push_back(newComponent);
}
}
Which is then used at the bottom of each component's header:
Register 2DPosReg(&2DPos);
Which makes sure that before we get to our main code all components are listed in Components. In the same fashion I also add the names of these components and some other details to some global vectors.
However, it seems unnecesarily messy to create a temporary object that never gets used just to execute code in it's constructor.
Is there any other way where including the header will make itself 'known' to the rest of the code?
I'd like to avoid my previous solution where I had a long Register(&2DPos, &Vel, &Acc, ...etc) function that would register all options, as any changes to the used components would require re-editing this function.
(Also, first stackoverflow question, apologies if it's long / has beginners mistakes)
However, it seems unnecesarily messy to create a temporary object that never gets used just to execute code in it's constructor.
You are correct with your assessment of the solution's aesthetic qualities. Unfortunately C++ doesn't have a better mechanism to accomplish what you are after.
After all, even the C++ standard library has to employ this technique when it wants to instrument code for execution after header inclusion.
Though, since you did mark this C++17, and you intended to put the object declaration in a header, you need to make it an inline variable:
inline Register whatevs(...);
It should produce one object per-header file.
I want to have items created using c++ macros like this:
#define PROPERTIES\
UPROPERTY(blabla)\
variableType varName;\
UPROPERTY(blabla)\
variableType2 varName2;
So I can add properties to other files including this and using PROPERTIES macro on them.
class XYZ...
{
...
public:
PROPERTIES
...
UPROPERTY()
varibleType3 name3;
....
}
This design comes from a typical organization, where those parameters come from another class because they are related to that class.
So I could include diferent files, and include all properties to show in the editor from all of them.
What's happening is that the Unreal Header Tool completely ignores UPROPERTY, of course, probably because it's being processed before and then the Macro... surprisingly is working but only the variable, not UPROPERTY... So the editor doesn't show it.
Any ideas on how to do this?
Are you sure that your properties are defined correctly? You should use something like UPROPERTY(EditAnywhere, Category="My category") Category is required when exposing Functions or Properties to editor. Properties with this macro would be exposed to instance properties editor and to class defaults editor as well.
Also I'd like to point out, that this design is really poor and I think that you may have problems with it. As you correctly pointed out, Epic has custom reflection system (UHT)which allows you to use automatic memory management with GC and so on. More on Build System UE Docs.
I think that you should decide how those properties will be used. Since you want to distribute them over multiple actors, you can choose from:
Inheritance
UObject reference
Component system
The first is really trivial and I believe you are familiar with this concept. And I think that you had your reasons why chose that macro solution. Note that you aren't allowed to use multiple inheritance (which is possible in classic C++) and this is due to UBT.
The second one goes like this:
UCLASS(BlueprintType)
class UMyProps : public UObject
{
// TODO define properties in a standard way
}
// some actor's properties
UPROPERTY(BlueprintReadWrite, Category = "My Game | My Subcategory")
UMyProps* myProperties;
Main advantage of the second system is that you can add sets of properties to objects that requires them while having type-safe environment and full Intellisence support (and UE Editor as well of course).
Or you can use Components, which is more or less like the second approach, but it could be totally dynamic (you don't need actual reference to your component, you can get it by calling GetComponent(...)).
These three are good, solid and transparent approaches to extend your object's properties. By using your macro's approach, you could easily ends up with a mountain of a mess, if this even works with UE build system).
I am kind of a newbie and I am creating a framework to evolve objects in C++ with an evolutionary algorithm.
An evolutionary algorithm evolves objects and tests them to get the best solution (for example, evolve the weights neural network and test it on sample data, so that in the end you get a network which has a good accuracy, without having trained it).
My problem is that there are lots of parameters for the algorithm (type of selection/crossover/mutation, probabilities for each of them...) and since it is a framework, the user should be able to easily access and modify them.
CURRENT SOLUTION
For now, I created a header file parameters.h of this form:
// DON'T CHANGE THESE PARAMETERS
//mutation type
#define FLIP 1
#define ADD_CONNECTION 2
#define RM_CONNECTION 3
// USER DEFINED
static const int TYPE_OF_MUTATION = FLIP;
The user modifies the static variables TYPE_OF_MUTATION and then my mutation function tests what the value of TYPE_OF_MUTATION is and calls the right mutation function.
This works well, but it has a few drawbacks:
when I change a parameter in this header and then call "make", no change is taken into account, I have to call "make clean" then "make". From what I saw, it is not a problem in the makefile but it is how building works. Even if it did re-build when I change a parameter, it would mean re-compile the whole project as these parameters are used everywhere; it is definitely not efficient.
if you want to run the genetic algorithm several times with different parameters, you have to run it a first time then save the results, change the parameters then run it a second time etc.
OTHER POSSIBILITIES
I thought about taking these parameters as arguments of the top-level function. The problem is that the function would then take 20 arguments or so, it doesn't seem really readable...
What I mean about the top-level function is that for now, the evolutionary algorithm is run simply by doing this:
PopulationManager myPop;
myPop.evolveIt();
If I defined the parameters as arguments, we would have something like:
PopulationManager myPop;
myPop.evolveIt(20,10,5,FLIP,9,8,2,3,TOURNAMENT,0,23,4);
You can see how hellish it may be to always define parameters in the right order !
CONCLUSION
The frameworks I know make you build your algorithm yourself from pre-defined functions, but the user shouldn't have to go through all the code to change parameters one by one.
It may be useful to indicate that this framework will be used internally, for a definite set of projects.
Any input about the best way to define these parameters is welcome !
If the options do not change I usually use a struct for this:
enum class MutationType {
Flip,
AddConnection,
RemoveConnection
};
struct Options {
// Documentation for mutation_type.
MutationType mutation_type = MutationType::Flip;
// Documentation for integer option.
int integer_option = 10;
};
And then provide a constructor that takes these options.
Options options;
options.mutation_type = MutationType::AddConnection;
PopulationManager population(options);
C++11 makes this really easy, because it allows specifying defaults for the options, so a user only needs to set the options that need to be different from the default.
Also note that I used an enum for the options, this ensures that the user can only use correct values.
This is a classic example of polymorphism. In your proposed implementation you're doing a switch on constant to decide which polymorphic mutation algorithm you will choose to decide how to mutate the parameter. In C++, the corresponding mechanisms are templates (static polymorphism) or virtual functions (dynamic polymorphism) to select the appropriate mutating algorithm to apply to the parameter.
The templates way has the advantage that everything is resolvable at compile time and the resulting mutating algorithm could be inlined entirely, depending on the implementation. What you give up is the ability to dynamically select parameter mutation algorithms at runtime.
The virtual function way has the advantage that you can defer the choice of mutation algorithm until runtime, allowing this to vary based on input from the user or whatnot. The disadvantage is that the mutation algorithm can no longer be inlined and you pay the cost of a virtual function call (an extra level of indirection) when you mutate the parameter.
If you want to see a real example of how "algorithmic mutation" can work, look at evolve.cpp in my Iterated Dynamics repository on github. This is C code converted to C++ so it is neither using templates nor using virtual functions. Instead it uses function pointers and a switch-on-constant to select the appropriate code. However, the idea is the same.
My recommendation would be to see if you can use static polymorphism (templates) first. From your initial description you were fixing the mutation at compile-time anyway, so you're not giving anything up.
If that was just a prototyping phase and you intended to support switching of mutation algorithms at runtime, then look at virtual functions. As the other answer recommended, please shun C-style coding like #define constants and instead use proper enums.
To solve the "long parameter list smell", the idea of packing all the parameters into a structure is a good one. You can achieve more readability on top of that by using the builder pattern to build up the structure of parameters in a more readable way than just assigning a bunch of values into a struct. In this blog post, I applied the builder pattern to the resource description structures in Direct3D. That allowed me to more directly express these "bags of data" with reasonable defaults and directly reveal my intent to override or replace default values with special values when necessary.
This is a followup question on my previous question:
Initialize const members using complex function in C++ class
In short, I have a program that has a class Grid that contains the properties of a 3D grid. I would like the properties of this grid to be read-only after creation, such that complex functions within the class cannot accidentally mess the grid up (such as if(bla = 10), instead of if(bla == 10)) etc. Now, this question has been answered well in the previous discussion: calling an initializer lists via a create function.
Here comes my new problem. My Grid has many properties that just plainly describe the grid (number of grid points, coordinates at grid points etc.) for which it just does not make sense to redistribute them among different objects. Still, basic textbooks in C++ always link functions with a large number of parameters to bad design, but I need them in order to be able to have const member variables.
Are there any standard techniques to deal with such problems?
The answer depends on what you're trying to protect.
If you're trying to assure that users of the class can't inadvertently alter the critical parameters, then the way to do that is to declare these members as private or protected and only provide const getters if they're needed at all outside the class implementation.
If you're trying to assure that the implementer of the Grid class doesn't alter these values, then there a few ways to do so. One simple way is to create a subclass that contains just those parameters and then the answer looks just like 1. Another way is to declare them const in which case they must be initialized when a Grid instance is constructed.
If the answer is 2, then there are also some other things that one can do to prevent inadvertently altering critical values. During the time that you're writing and testing the class implementation, you could temporarily use fixed dummy const values for the critical parameters, assuring that the other functions you write cannot alter those values.
One more trick to avoid specifically the if (i=7) ... error when you meant to write if (i == 7) ... is to always put the constant first. That is, write if (7 == i) .... Also, any decent compiler should be able to flag a warning for this kind of error -- make sure you're taking advantage of that feature by turning on all of the warning and error reporting your compiler provides.