How do i use parameters with constructors? - c++

I am programming in ue5 and i was creating a spatial hash. i needed to have a declared cell size for the hash, and i decided to use the constructor
Here is a similar code
HSpatialHash.h
UCLASS()
class xxx_API UHSpatialHash final : public UObject
{
GENERATED_BODY()
public:
explicit UHSpatialHash(const float PCellSize) {CellSize = PCellSize;}
}
Error message:
error C:\Users\user\OneDrive\Documents\Unreal Projects\attrition\Source\project name\Private\HSpatialHash.h(18):
error C2338: static_assert failed: 'You have to define UHSpatialHash::UHSpatialHash() or UHSpatialHash::UHSpatialHash(const FObjectInitializer&).
This is required by UObject system to work correctly.'
I tried to add the FObjectInitializer parameter, but it didn't work. I tried to put in in the cpp file, nothing, i don't know what to do. Can you help me?

If you inherit from UObject, you have to provide either a default constructor or the one with the FObjectInitializer parameter. You create the object using NewObject() which does some internal initialization logic for the object and you can't pass parameters to it.
i decided to use the constructor
Depending on what you want to do, you probably should change your decision.
Do you need it to be a UObject with reflection and editor visibility? Because then, it would be easier to just add an "Initialize()" method with the parameters you wanted to have in the constructor and call it after creation, like so:
UCLASS()
class xxx_API UHSpatialHash final : public UObject
{
GENERATED_BODY()
public:
inline void Initialize(const float PCellSize) { CellSize = PCellSize; }
}
and for creation:
UHSpatialHash* spatialHash = NewObject<UHSpatialHash>(this);
spatialHash->Initialize(cellSize);
If you only want it to be a simple class without reflection, you can just use a regular C++ class and use your custom constructor.
Another option would be to use a USTRUCT() instead. It can't do as much as the UCLASS(), but since you do not intent to inherit from it, it may be enough. You can define a custom constructor and do not need to care for the FObjectInitializer parameter.

Related

Cast mock objects to their abstract base class in C++

I have a class looking somewhat like this:
class TheClassIWantToTest {
public:
TheClassIWantToTest(const IInput& input) {
setLocalParameter(input.getParameter());
}
// other stuff, e.g. setLocalParameter, defined below
}
where the input argument is defined as
class IInput {
virtual double getParameter() const = 0;
}
I also have an implementation of IInput which I use in my system, and a mock implementation created with Google Mocks.
Now, I want to be able to do something like
MockInput mock; // MockInput : IInput
TheClassIWantToTest sut(mock);
in my tests, while doing
RealInput theRealStuff; // RealInput : IInput
TheClassIWantToTest(theRealStuff);
but when I try to compile, I get errors about no method TheClassIWantToTest(MockInput) being defined. I tried to define a copy-constructor for IInput that takes a MockInput, but then I get error: definition of implicitly-declared IInput(const MockInput&) since I haven't defined the method in my class declaration.
However, I'd rather avoid declaring the copy constructor in the base class definition, since that would mean defining test methods in my production code. (I realize I could solve this by just taking a IInput* pointer instead, but if possible I'd like to avoid this too.)
I can't imagine I'm the first to try to accomplish this, but I haven't been able to find out how to do it. Is there a way? If so, how do you do it?
Try the dynamical cast:
RealInput theRealStuff; // RealInput : IInput
TheClassIWantToTest(dynamic_cast<const IInput&>(theRealStuff));

Avoid repetitive constructor for user-defined inherited classes

// Library code
struct Entity;
struct Attachment {
Entity& entity;
Attachment(Entity& mEntity) : entity(mEntity) { }
};
// ---
// User code
struct MyAttachment1 : Attachment {
// This is annoying to write for every attachment type
// Especially when there are other constructor arguments
// And if there are a lot of attachment types
MyAttachment1(Entity& mEntity) : Attachment{mEntity} { }
};
struct MyAttachment2 : Attachment {
MyAttachment2(Entity& mEntity) : Attachment{mEntity} { }
};
// ...
As you can see from the code example, every type that derives from Attachment needs to define a repetitive constructor where an Entity& is passed to the base class constructor.
This would not be an issue, but in my projects I deal with 40-50+ attachments, and they also have their own parameters in their constructors.
It seems unnecessary having to explicitly pass Entity& as the first parameter.
One workaround I've found is using a virtual void Attachment::init() method that the user overrides, and that is called by the Entity after an Attachment has been added to it. This, however, uses an unnecessary virtual call and still requires the user to deal with boilerplate code.
Is there a more elegant way to deal with this problem?
No. There is not a more elegant way to write it. I can't even fathom how typing Attachment{mEntity} when you are writing a class constructor can possibly be considered a chore. I mean, you're writing a whole class anyway. If it's such a bother, create a macro in your text editor.
Not sure if it helps, but in C++11 you can also do
struct MyAttachment1 : Attachment {
// Note, this imports ALL of the base constructors, you can't
// pick and choose
using Attachment::Attachment;
};
See https://ideone.com/fceV4k

Object Construction in C++

I am working on a small project in C++ that requires me to create an object of a custom class I wrote in another one of my classes. The class is called FIRFilterModule, It has a simple blank constructor.
Being of a java background, my impulse is to create it like this:
class SensorInput{
public:
FIRFilterModule firFilter;
...More Class Members...
SensorInput():firFilter(FIRFilterModule()){}
...};
However this compiles with the ever so helpful error message of "Error within this context". I'm a little lost why that doesn't work. Increasing my confusion I changed the code to this:
class SensorInput{
public:
FIRFilterModule firFilter;
...More Class Members...
SensorInput(){}
...};
It works.
Can someone help me understand why this is so?
In this particular case, running of the default constructor for a member field, you don't have to do anything. The constructor is run automatically. So you can just write
class SensorInput{
public:
FIRFilterModule firFilter;
SensorInput() { ... }
};
The member initialization list is only needed when you need to call a constructor which has arguments or initialize POD types. For example say the FIRFilterModule had a constructor which took an int. Then you would use the memeber initialization list
SensorInput() : firFilter(42) { ... }
The code you posted is correct.
Maybe you forgot to include the header where FIRFilterModule is declared.
Otherwise, everything should work.

Generating a derived class instance from a string of its name. (i.e, reflection)

If I have a base class:
class Base
{
public:
virtual void Test()=0;
};
and, in a dynamically loaded module (.so/.dll), I implemented a class derived from this:
class SomethingFromBase : Base
{
...
};
and, the user, once this library is loaded, asks to create an instance of SomethingFromBase (let's say we get the name from cin.), and, we have no knowledge of SomethingFromBase (i.e, no way to just do if(inputstr == "SomethingFrombase") { ... } is there any way to create an instance of SomethingFromBase?
I'm fairly certain this is impossible in (standard) C++, but, I'm always hoping SO will surprise me!
If this is possible with the addition of some library, I'd still like to know about it.
Thanks!
Edit: See cdhowie's answer. Guides to implementing this technique:
http://www.linuxjournal.com/article/3687?page=0,1
http://www.abstraction.net/ViewArticle.aspx?articleID=67
You typically achieve this by required that plugin libraries define some global variable of a struct type that contains pointers to various functions you can call. (Like setup, teardown, etc.) During the setup function, they would call back into your application to some "register" function where they could pass in a string representing the name of the class, and a factory function pointer that will create an instance when executed.
You stash this away in some map, and when the user enters a string, you look at the map to see if there is a factory function registered. If so, just call it.
So this is not "true" reflection, but you can manually hack it to some degree. See, for example, Pidgin, which allows the specification of protocol plugins that may supply many entries in the protocol list.
EDIT: Here is a nifty guide to implementing something similar. I'm more of a C person, so I can't vouch for it being truly awesome or anything, but at first glance it looks good. I've done similar stuff in C on Linux, and the basic approach works pretty well.
Have a map store the objects of the class, keyed by the class name.
All the classes that need to be created this way, need to be derived from some base class named something like "Creatable"
The code to add the object of the class need to be given with the implementation of class.
//Creatable.h
#define IMPLEMENT_CREATABLE( ClassName ) \
ObjectMap::Instance().Add( string(ClassName), new ClassName );
//ObjectMap.h. This is a singleton
class ObjectMap
{
...........
map<string, Creatable *> myMap;
...........
public:
void Add( const string &className, Creatable * );
Creatable * Get( const string &className );
};
//My Class.h
class MyClass : public Creatable
{
................
};
//My Class.cpp
IMPLEMENT_CREATABLE(MyClass);
//Client.cpp
string className;
cin>>className;
Creatable *anObject = ObjectMap::Instance().Get( className );

How to refrain from CS2512 correctly

Please help me with the following problem:
I have the following classes:
class ChemicalElement
{
private:
std::string _name;
void Init(const std::string& name);
public:
ChemicalElement(const std::string& name);
ChemicalElement(const ChemicalElement& ce);
};
class CombinationRule
{
private:
ChemicalElement _ce1;
ChemicalElement _ce2;
void Init(const ChemicalElement& ce1, const ChemicalElement& ce2);
public:
CombinationRule(const ChemicalElement& ce1, const ChemicalElement& ce2);
CombinationRule(const CombinationRule& rule);
};
The implementation is obvious. I intended to initialize the CombinationRule using the Init method to minimize code duplication. Alas, if I do not use "member initialization list" in each constructor the compiler complains with "error C2512: 'ChemicalElement' : no appropriate default constructor available". Is there an elegant way to solve this error instead of using a default constructor or member initialization list?
BTW: if there are any other problems in the classes definition please add it too. Since I'm revisiting C++ I want to be aware of them.
You should implement constructors of CombinationRule as follows so they will use appropriate constructors of ChemicalElement:
CombinationRule::CombinationRule(const ChemicalElement& ce1,
const ChemicalElement& ce2) : _ce1(ce1), _ce2(ce2)
{
...
}
CombinationRule::CombinationRule(const CombinationRule& rule) :
_ce1( rule._ce1 ), _ce2( rule._ce2 )
{
...
}
I think you are required to put a default constructor in any class where you define any other constructors, if you want to use objects of that class in any kind of array or container. The default constructor's implementation can just be an empty/no-op method though.
You shouldn't need to put in a member initialization list (although using a member initialization list can be more efficient in some cases, since that way your member variables are only initialized once, instead of being initialized once via their default constructor, and then written to a second time by your Init() method)
I think you want this
ChemicalElement * ce1;
I say this because I think its trying to run the default constructor on your CombinationRule and in turn needs to get a ChemicalElement for ce1 and ce2 ... but I could be wrong.
Pretty sure Krill's way is the way to specify the constructor of a variable for a specific constructor BUT i said f that and just made it so ce1 doesn't need to be constructed by the compiler :)
In this particular example I would go on with duplication (it's just writing two initializers, nothing to get obsessive about).
But assuming the real story is more complex: use OO facilities to avoid code duplication.
class CombinationRule : public ElementPair ...
or
class Combination { ElementPair twoElements; ...}
Where ElementPair contains two ChemicalElements and a single constructor (with common code), and Combination rule constructors initialize using constructor of ElementPair.
There are other approaches: initializing members with some InvalidChemicalElement instance or using pointers (auto_ptr) with NULL for InvalidChemicalElement.