I have a function in an pure virtual class that is inheritted by multiple classes. This function looks something like:
virtual quint32 myClass::getIntValue() = 0
In some classes that inherrit this function a default value should be returned since they cannot implement this function (yet). However any quint32 that I pick can also be a valid return value. So for example if I pick "0" to be the default value, I can check the return value to be "0" and act accordingly (for example ignoring that value). However there will be cases when "0" will be a valid return value that makes sense.
Is there any way around this problem?
Use boost::optional. Hopefully it'll be added to the C++17 standard.
You could return a QPair or pass a bool& like:
virtual quint32 myClass::getIntValue(bool &valid) = 0;
or
virtual QPair< quint32,bool > myClass::getIntValue() = 0;
If you can use an optional type, use it.
Otherwise, since the caller of getIntValue has to do the checks anyway, it'd be useful to force it to do the checks. Have a method the caller can use to check if getIntValue is implemented. A quick inspection of such an API makes it obvious that you need to call hasGetIntValue before you use it. It self-documents not much worse than had you used an optional type.
class MyClass {
...
virtual quint32 getIntValue() const { Q_ASSERT(false); } // or abort()
virtual bool hasGetIntValue() const { return false; }
};
class Class : public MyClass {
...
quint32 getIntValue() const Q_DECL_OVERRIDE { return 42; }
bool hasGetIntValue() const Q_DECL_OVERRIDE { return true; }
}
The caller can then check and avoid the call altogether:
if (myClassInstance.hasGetIntValue()) {
auto value = getIntValue();
...
} else {
// can't call getIntValue(), do something else
}
This approach will catch callers that don't do the check at runtime.
Note that getters usually can be declared const, and reimplementations should be declared with Q_DECL_OVERRIDE to ensure that you're actually implementing existing virtual methods, not adding new ones.
An alternative approach would be to implement some lightweight optional value class if you can't use boost::optional for whatever reason.
Related
I am trying to mock a member method parseString so that:
It keeps its original behaviour, that is, it returns its original method return value and fills the output parameter (std::vector<std::string>& iReqs) as the original method;
I can check one of its output parameter (std::vector<std::string>& iReqs)
There is probably an easy way to do it, but I didn't find a clean way so far .
What I got closest the most is the following, with GMock:
Use a lambda to mimic the original method behaviour
Use SaveArgs to store the parameter
The problem with this approach is that SaveArgs doesn't return any value, and it makes the test crash compiling in release mode. If I invert the two DoAll statements, SaveArgs is called before the method actually fills it, so it's meaningless. If I add the step 3. and modify a little the step 1.:
Use a lambda to mimic the original method behaviour and store the original return value;
Use SaveArgs to store the parameter;
Return the original return value;
Then it seeems to work, except for one case in my tests, so it looks there may be some undefined behaviour hidden in this solution.
Code snippet:
class FooMock : public Foo
{
public:
FooMock() : Foo()
{
// By default, all calls are delegated to the real object.
// Moreover, we capture intermediary object for testing purposes
// We need to save _originalReturn otherwise we will have undef behaviour
ON_CALL(*this, parseString).WillByDefault(DoAll(
([this](const std::string& iDoc,
std::vector<std::string>& iReqs) {
_originalReturn = this->Foo::parseString(iDoc, iReqs);
return _originalReturn;
}),
SaveArg<1>(&_requests),
Return(_originalReturn)
));
}
MOCK_METHOD2(parseString, bool (const std::string& iDoc,
std::vector<std::string>& iReqs));
virtual ~FooMock() = default;
std::vector<std::string> _requests;
private:
bool _originalReturn = false;
};
class Foo
{
public:
Foo() = default;
virtual ~Foo() = default;
bool execute( const std::string& iMessage ) {
// Calling parseString here
return true;
}
protected:
virtual bool parseString(const std::string& iMessage,
std::vector<std::string>& oBom){
//Does something here
return true;
}
};
In the GTest I should be able to do the following:
TEST_F( FooMockTest, basicRequest )
{
std::string aString = "Something";
FooMock uc;
EXPECT_CALL(uc, parseString(_, _)).Times(1);
EXPECT_TRUE(uc.execute(aString));
// Test some property of the output parameter...
ASSERT_EQ(1U, uc._requests.size());
}
Again, I can't find a way to concatenate the two behaviours I would like for my mocked member method, preserving its original behaviour and saving the args after its original execution.
I think my latest snippet is not safe and may hide some inconsistency (since I pass through an intermediate variable as Mocked class member field).
Could you please help? Thanks!
First of all, I don't see any UB here. If you want to get help with that - create separate question.
About this one, I recommend for you to just use gMock matchers properly. Basically, you want some trivial thing, but you just using wrong tools for that. In your code you used placeholders in EXPECT_CALL instead of actual matchers:
EXPECT_CALL(uc, parseString(_, _)).Times(1);
Those placeholders must be used when you don't care which parameters was used during call. But you care about them and even created special field to compare them. So you just need to use proper matchers, in this case Container matchers to validate what items was used during that call. In you snippet you are validating amount of items, it can be done with SizeIs matcher:
EXPECT_CALL(uc, parseString(_, SizeIs(1))).Times(1);
There are a lot of other pretty complex matchers which can help you to match parameters in any scenario. For example you want to ensure that when parseString was called second input parameter contains one string which has substring "MAD". It will looks like this:
EXPECT_CALL(uc, parseString(_, Contains(HasSubstr("MAD")))).Times(1);
So my version for task described in question will looks like this:
class Foo {
public:
virtual ~Foo() = default;
bool execute(const std::string& iMessage)
{
std::vector<std::string> Bom;
Bom.push_back("first_item");
return parseString(iMessage, Bom);
}
protected:
virtual bool parseString(const std::string& iMessage,
std::vector<std::string>& oBom)
{
oBom.push_back("extra_item");
return true;
}
};
class FooMock : public Foo {
public:
FooMock()
{
ON_CALL(*this, parseString).WillByDefault([this](const std::string& iDoc, std::vector<std::string>& iReqs) {
return Foo::parseString(iDoc, iReqs);
});
}
MOCK_METHOD2(parseString, bool(const std::string& iDoc, std::vector<std::string>& iReqs));
};
TEST(FooMockTest, basicRequest)
{
std::string aString = "Something";
FooMock uc;
EXPECT_CALL(uc, parseString(aString, SizeIs(1))).Times(1);
EXPECT_TRUE(uc.execute(aString));
}
In this case we will validate that parseString will be called once during call of execute method, it will receive same string which was passed to execute and vector with one item (in this case vector which contains "first_item" element).
I'm working with the following class design and would like to get rid of the same for-loop in each of the forwarding method calls by using some sort of delegate/member pointer. Is this somehow possible?
class Type
{
void func_v();
// more methods ...
bool func_b();
// ...
unsigned func_u();
// ...
}
class MultiType : public Type
{
void func_v() override
{
for(Type* type : _typeVec)
type->func_v();
}
bool func_b() override
{
bool result = true;
for(Type* type : _typeVec)
result = result && type->func_b();
return result;
}
unsigned func_u() override
{
int count = 0;
for(Type* type : _typeVec)
count += type->func_u();
return count;
}
protected:
std::vector<Type*> _typeVec;
}
What I'm looking for is something similar to this:
class MultiType : public Type
{
void applyMember(MemberType member)
{
for(Type* type : _typeVec)
// how to deal with varying parameters and parameter types here?
type->member(...)
// how to deal with varying return values and processing strategies to combine those?
}
void func_v() override
{
applyMember(&Type::func_v);
}
bool func_b() override
{
applyMember(&Type::func_b);
}
unsigned func_u() override
{
applyMember(&Type::func_u);
}
protected:
std::vector<Type*> _typeVec;
}
Since all your example functions perform different actions I would recommend you to look into accumulate and for_each algorithms.
You could replace your raw loops with something like this:
bool func_b() override
{
return std::accumulate(_typeVec.begin(), _typeVec.end(), true, [](const bool &result, const Type *t) {
return result && type->func_b();
});
}
void func_v() override
{
std::for_each(_typeVec.begin(), _typeVec.end(), [](Type *type){type->func_v()});
}
The "What I'm looking for..." part in your question doesn't work. For example, func_b doesn't return any value. Even if you could do something like that using a combination of template functions and lambdas, you'd have the same independent parts in all functions (local variable declaration, reduction mechanism, return statement). The only thing you could abstract away is the for loop, but that's just a single line you'll be replacing with a different line.
There's no point doing that.
From what I understand of your question, you would want to call the same method, and possibly use the same parameters, on each object.
For example, in your production code, func_v would take parameters. This may be different from func_b that may not take parameters.
Let us assume that func_v takes in a int.
In this case, would this be true?
MultiType::func_v(int value) {
for (Type* type : _typeVec)
type->func_v(value); //note: same value being passed to all
}
You may want to use functors here. However, I don't think that will work well with multiple return values.
Functors can be used to aggregate values. Is that what you want to do?
Forgetting abstracting the loop out, how will you return multiple values from func_v above?
So if returning multiple values is not a problem, functors can be what you want to do.
It may be too much work for too little though. You will have to find out if it is worth it in your production code.
I have a class whose member itemType is only set once and never modified but it is used in many if-statements to decide which function to call.
Since itemType is only set once is there way to avoid the if statements else where in the class. This will simplify and clean the code and as a bonus will also save the overhead of if checks.
I was thinking about function a pointer taht I can initiatlize in the constructor based on the itemType value.
Is there any alternate and a better way of doing that?
Please note the original class and code base is large and I cant go around creating child classes based on itemtype.
enum ItemTypes
{
ItemTypeA,
ItemTypeB,
};
class ItemProcessing
{
public:
//This function is called hundreds of times
void ProcessOrder(Order* order)
{
//This member itemType is set only once in the constructor and never modified again
//Is there a way to not check it all the time??
if (itemtype == ItemTypes::ItemTypeA )
{
ProcessTypeA(order)
}
else if (itemtype == ItemTypes::ItemTypeB )
{
ProcessTypeB(order)
}
}
ItemProcessing(ItemTypes itype)
{
itemtype = itype; //can I do something here like setting a function pointer so I dont have to check this property in ProcessOrder() and call the relevant function directly.
}
private:
ItemTypes itemtype;
void ProcessTypeA(Order*);
void ProcessTypeB(Order*);
};
Use an array of function pointers, indexed by itemtype, like this:
typedef void(*ProcessType_func_t)(Order *);
ProcessType_func_t processType_f[] = {
ProcessTypeA,
ProcessTypeB
};
Then you can do:
void ProcessOrder(Order *order) {
ProcessType_f[itemtype](order);
}
If you have lots of different functions that need to be dispatched like this, you can use a structure.
struct {
ProcessType_func_t processType_f,
OtherType_func_t otherType_f,
...
} dispatchTable[] = {
{ ProcessTypeA, OtherTypeA, ... },
{ ProcessTypeB, OtherTypeB, ... }
};
Then you would use it as:
dispatchTable[itemtype].processType_f(order);
Finally, you could do the fully object-oriented method, by defining new classes:
class Processor { // abstract base class
public:
virtual void Process(Order *order) = 0;
};
class ProcessorA {
public:
void Process(Order *order) {
ProcessTypeA(order);
}
}
class ProcessorB {
public:
void Process(Order *order) {
ProcessTypeB(order);
}
}
Then you can have a member variable
Processor *processor;
and you initialize it when you set itemtype
ItemProcessing(ItemTypes itype)
{
itemtype = itype;
if (itemtype == ItemTypeA) {
processor = new ProcessorA;
} else {
processor = new ProcessorB;
}
}
Then you would use it as:
processor->Process(order);
This is easily expanded to support more functions that need to dispatch on itemtype -- they all become methods in the classes.
I hope I got the syntax right, I don't actually do much C++ OO programming myself.
You can consider to use either a couple of pointers to member methods or the state pattern.
The former solution has probably higher performance, while the latter is more elegant and flexible (at least from my point of view).
For further details on the state pattern, see here. This pattern fits well with your problem, even though you have to refactor a bit your classes.
I guess the first suggestion is indeed quite clear and does not require further details.
In c++ pointer to function should be mimic with virtual function and inheritance. (Polymorphism)
Define a virtual class including a pure virtual methods
processOrder ( Order* ordre);
And define subclass for each value of your enum.
You can use abstract factory pattern to creat those object or either if needed.
I can write the code if wish.
For a class, which is only defined in a header, I need a special behavior of one method for all instance of the class. It should be depending on a default value, which can be changed any time during runtime. As I do not want a factory class nor a central management class I came up with that idea:
class MyClass
{
public:
void DoAnything() // Methode which should be act depending on default set.
{
// Do some stuff
if(getDefaultBehaviour())
{
// Do it this way...
}
else
{
// Do it that way...
}
}
static bool getDefaultBehaviour(bool bSetIt=false,bool bDefaultValue=false)
{
static bool bDefault=false;
if(bSetIt)
bDefault=bDefaultValue;
return bDefault;
}
};
It works, but it looks a little awkward. I wonder if there is a better way following the same intention.
In the case where I want to use it the software already created instances of that class during startup and delivered them to different parts of the code. Eventually the program gets the information how to treat the instances (for e.g. how or where to make themselves persistent). This decision should not only affect new created instances, it should affect the instances already created.
I'd advise to use a simple method to simulate a static data member, so the usage becomes more natural:
class MyClass
{
public:
// get a reference (!) to a static variable
static bool& DefaultBehaviour()
{
static bool b = false;
return b;
}
void DoAnything() // Methode which should be act depending on default set.
{
// Do some stuff
if(DefaultBehaviour())
{
// Do it this way...
}
else
{
// Do it that way...
}
}
};
where the user can change the default at any time with
MyClass::DefaultBehaviour() = true;
My thanks to Daniel Frey with his answer which I already marked as the best. I wanted to add my final solution which is based on the answer from Frey. The class is used by some c++ beginners. As I told them to use always getter and setter methods, the way described by Frey looks very complex to beginners ("uuuh, I can give a function a value?!?!"). So I wrote the class like followed:
class MyClass
{
public:
// get a reference (!) to a static variable
static bool& getDefaultBehaviour()
{
static bool b = false;
return b;
}
static void setDefaultBehaviour(bool value)
{
getDefaultBehaviour()=value;
}
void DoAnything() // Methode which should be act depending on default set.
{
// Do some stuff
if(getDefaultBehaviour())
{
// Do it this way...
}
else
{
// Do it that way...
}
}
};
for the user, I looks now like a usual getter and setter.
I'm trying to add another function to a large program I've been working on. It's a 3D game, and a lot of it was built before I got here. If I want to add something, I'll usually look for other places where something similar has been done and make my changes based off that. In this instance however the method I'm trying to learn from is very complex and I don't really know what is going on (and thus don't know what I need to change about it to make it do what I want it to do).
Here is the normal method:
class Action_GoToZone : public Action {
public:
Action_GoToZone() {}
void eval(const Dialog& dialog, State& state) const {
ZoneParser::getSingleton().load("../media/zones/" + mZoneFilename, false);
GameState::getSingleton()._changeState("GameMode");
}
static Action* Create(const Script2::Parser::List& list) {
Action_GoToZone* action = new Action_GoToZone();
if(list.size() != 1)
throw Translator::TranslateException("GoToZone Action takes exactly one parameter");
const Script2::Parser::ListElement& e1 = list.front();
if(!e1.mIsIdentifier)
throw Translator::TranslateException("GoToZone Action only takes identifiers");
action->mZoneFilename = String(e1.mIdentifier.mString);
action->mReturnFilename = ZoneParser::getSingleton().getLastFilename();
return action;
}
private:
String mZoneFilename;
String mReturnFilename;
};
All I want my method to do is to call a function within a different class. Here is what I attempted:
class Action_SetJob : public Action {
public:
Action_SetJob() {}
void eval(const Dialog& dialog, State& state) const {
GameModeState::changeJob(1); //This is the class/function I want it to call.
}
static Action* Create(const Script2::Parser::List& list) {
Action_SetJob* action = new Action_SetJob();
if(list.size() != 1)
throw Translator::TranslateException("SetJob Action takes exactly one parameter");
const Script2::Parser::ListElement& e1 = list.front();
if(!e1.mIsIdentifier)
throw Translator::TranslateException("SetJob Action only takes identifiers");
action->GameModeState::changeJob(1);
return action;
private:
int changeJob;
}
};
I don't really know what action-> is for... I tried it with taking out action->GameModeState::changeJob(1); and all content below that but that threw up errors.
This probably isn't enough information to solve the problem, but I'd be happy with any explanation about the method, if you can.
If I understand correctly what you are trying to do, then this should accomplish it:
class Action_SetJob : public Action {
public:
Action_SetJob() {}
void eval(const Dialog& dialog, State& state) const {
GameModeState::changeJob(newJob);
}
static Action* Create(const Script2::Parser::List& list) {
Action_SetJob* action = new Action_SetJob();
if(list.size() != 1)
throw Translator::TranslateException("SetJob Action takes exactly one parameter");
const Script2::Parser::ListElement& e1 = list.front();
if(!e1.mIsInteger)
throw Translator::TranslateException("SetJob Action only takes integers");
action->newJob = e1.mInteger.mInt;
return action;
}
private:
int newJob;
};
Obviously since C++ is context-sensitive (it's actually an undecidable language), I cannot know what other members your classes have so I guessed what could be likely.
You want to parse an integer that you can pass to the function you are trying to call when the action gets evaluated.
This is assuming your changeJob method is static. If it is not actually static, you will have to somehow figure out the target object; you can do that by adding an other parameter to your script function for example.
If you want more details, we need more information!
-> is a pointer reference. It looks like your objects are pointers (from the * after the object type). Is the problem with the pointer operations or with something else? From what you wrote, I'm not exactly sure what entirely to offer help with aside from your mention of action->