Reputation: 313
I am invoking the below function from different classes and files like as shown below. And the implementation is almost similar. But it is initializing in the respective class constructor.
Can I create a common function for the below code for all the classes and then when invoking, based on the class can I initialize and return the object?
Below is the function with almost similar implementation for all the classes. And I have this similar implementation in around 10 places.
Could someone please suggest me the better approach to create a common reusable function?
1.
shared_ptr<CTestOneImpl> COneImpl::createTestObject(const string& f_strSFID, short f_nID,
bool f_bIsVerified,
bool f_bIsProcessed)
{
shared_ptr<CTestOneImpl> l_pTestObj = nullptr;
l_pTestObj = make_shared<CTestOneImpl>(f_nID, f_strSFID,
f_bIsVerified, f_bIsProcessed,
this);
return l_pTestObj;
}
shared_ptr<CTestTwoImpl> CTwoImpl :: createTestObject(string f_hStrSFID, long f_nID,
bool f_bIsVerified,
bool f_bIsProcessed)
{
shared_ptr<CTestTwoImpl> l_pTestObj = nullptr;
l_pTestObj = make_shared<CTestTwoImpl>(f_nID, f_hStrSFID, f_bIsVerified
, f_bIsProcessed, this);
return l_pTestObj;
}
shared_ptr<CTestThreeImpl> CThreeImpl ::createTestObject(const string& f_strSFID,
const string& f_nID,
bool f_bIsVerified,
bool f_bIsProcessed)
{
shared_ptr<CTestThreeImpl> l_pTestObj = nullptr;
l_pTestObj = make_shared<CTestThreeImpl>(f_nID,
f_strSFID,
f_bIsVerified,
f_bIsProcessed,
this);
return l_pTestObj;
}
Updated code using templatized class based on the inputs:
.h file
#include <iostream>
#include <list>
template <typename RetType, typename Args1, typename Args2, typename Args3>
class CTestImpl
{
public:
CTestImpl(std::string f_lCallIdentifier, bool f_bIsVerified,
bool f_bIsProcessed);
private:
std::shared_ptr<RetType>
createTestObject(Args1&& f_strSFID, Args2&& f_bIsVerified, Args3&& f_bIsProcessed);
public:
void handleEvents(const std::string& f_eCallEvent, const std::string& f_strSFID);
};
.Cpp file
#include "TestImpl.h"
template <typename RetType, typename Args1, typename Args2, typename Args3>
// error: C2976: 'CTestImpl': too few template arguments
std::shared_ptr<RetType> CTestImpl<RetType>::createTestObject(Args1&& f_strSFID, Args2&& f_bIsVerified, Args3&& f_bIsProcessed)
// error: C2244: 'CTestImpl::createTestObject': unable to match function definition to an existing declaration
{
return std::make_shared<RetType>(std::forward<Args1>(f_strSFID),
std::forward<Args1>(f_bIsVerified),
std::forward<Args1>(f_bIsProcessed));
}
//error: C2955: 'CTestImpl': use of class template requires template argument list
void CTestImpl::handleEvents(const std::string& f_eCallEvent, const std::string& f_strSFID)
{
// error: C2509: 'handleEvents': member function not declared in 'CTestImpl'
shared_ptr<CTestImpl> l_hCallObj = nullptr;
l_hCallObj = createTestObject(f_strSFID, true, false);
}
Upvotes: 0
Views: 98
Reputation: 394
You don't provide quite enough information, so I'm going to make some assumptions.
Assumptions
make_shared
pass the same variables so I assume this is the case.Solution Use polymorphism.
/**
* This is an interface that all of your test classes will need to implement.
*/
class ITest {
public:
~virtual ITest() = default;
virtual void CommonMethod(...) = 0;
};
class CTestOneImpl : public ITest {
void CommonMethod(...) override;
};
Assuming you are setup like the above for all 3 (or however many) of your classes, you can now create a factory class that will make some people sad.
class TestObjectFactory {
enum class TestType{
TestOne,
TestTwo,
TestThree
};
static std::shared_ptr<TestObject> MakeTestObject(TestType &t, ...) {
switch(t) {
case(TestOne): return std::make_shared<CTestOneImpl>(...);
....
default: return nullptr;
}
}
};
So when you want a CTestOneImpl, you just call auto test_obj_ptr = TestObjectFactory::MakeTestObject(TestObjectFactory::TestType::TestOne, ...)
Hope this answers your question, if it doesn't please provide some more info.
Upvotes: 0
Reputation: 66230
Not sure to understand what do you exactly want... but... what about as follows?
template <typename RetType>
shared_ptr<RetType> BaseClass::createTestObject (std::string const & f_strSFID,
short f_nID,
bool f_bIsVerified,
bool f_bIsProcessed)
{ return std::make_shared<RetType>(f_nId, f_strSFID, f_bIsVerified, f_bIsProcessed, this); }
Or, maybe better, if you pass the argument to createTestObject()
(this
also) in the same order required by the RetType
constructor
template <typename RetType, typename ... Args>
shared_ptr<RetType> BaseClass::createTestObject (Args && ...as)
{ return std::make_shared<RetType>(std::forward<Args>(as)...)); }
But, at this point, you can directly call std::make_shared()
.
Upvotes: 1