std::shared_ptr of abstract class to instantiate derived class
Solution 1
That's easy. Look at code and feel.
std::shared_ptr<IExecute> ppCIExecuteExecuteOperation;
for(int i = 0; i < 3; ++i)
{
switch (stOperationType.key)
{
case E_OPERATIONKEY::DrawCircle:
pCIExecuteExecuteOperation.reset(new CCircle());
break;
case E_OPERATIONKEY::DrawSquare:
pCIExecuteExecuteOperation.reset(new CSquare());
break;
case E_OPERATIONKEY::Rhombus:
pCIExecuteExecuteOperation.reset(new CRehombus());
break;
default:
break;
}
}
pCIExecuteExecuteOperation->Draw();
Solution 2
The method std::make_shared<T>
creates a shared pointer object of type T
and calls its constructor. So instead of calling new
call std::make_shared
.
std::shared_ptr<IEXectue>pCIExecuteExecuteOperation(nullptr);
...
...
switch (stOperationType.key)
{
case E_OPERATIONKEY::DrawCircle:
pCIExecuteExecuteOperation = std::make_shared<CCircle>();
break;
...
std::make_shared
is also able to use paramaters, which are forwarded to the constructor, assuming there is a construcotr with that paramater list.
Solution 3
The line
IExecute *ppCIExecuteExecuteOperation = NULL;
should be replace with
std::shared_ptr<IExecute> pExecute;
and then each of the lines with assignments can be written as
pExecute.reset(new CCircle);
Then you can call Draw
pExecute->Draw();
Barry
Updated on June 04, 2022Comments
-
Barry almost 2 years
I am trying to use
std::shared_ptr
, but i am not sure if i can useshared_ptr
for a abstract class and call a derived class from this smart pointer. Here is the code that i have at presentIExecute *ppCIExecuteExecuteOperation = NULL; for(int i = 0; i < 3; ++i) { switch (stOperationType.key) { case E_OPERATIONKEY::DrawCircle: pCIExecuteExecuteOperation = new CCircle(); break; case E_OPERATIONKEY::DrawSquare: pCIExecuteExecuteOperation = new CSquare(); break; case E_OPERATIONKEY::Rhombus: pCIExecuteExecuteOperation = new CRehombus(); break; default: break; } } pCIExecuteExecuteOperation->Draw();
Here IExecute is a abstract class and CCircle, CSquare, CRhombus is a derived class of IExecute.
All I want to do is use
shared_ptr<IEXectue>pCIExecuteExecuteOperation(nullptr)
and inside a switch statement make it point to one of the derived class, How can i achieve this?Edit: The answers were to use make_shared or reset()
Thanks guys, I dint expect it to be so easy.
-
evotion over 9 yearsIsn't it safer in terms of memory leaks to use
std::make_shared
instead ofnew
? -
ikh over 9 years@evotion why? could you explain me?
-
evotion over 9 yearsThe notes at cppreference show this. Well the question is, if this code is even good practice, because it is hard to read without make_shared, but it can lead to problems.
-
ikh over 9 years@evotion No, that's okay to directly
new
in this case. The point of that cppref page is relate to order of evalution, but in my case that doesn't occur. -
Barry over 9 yearsThank you guys, but i want to know what is the difference in using std::make_shared and "new" as mentioned in the above code
-
evotion over 9 yearsIn this case not because you are using reset instead of constructing a new shared_ptr by calling the std::shared constructor. I never seen that use of
reset()
. Is there any reason preferringreset()
? In my opinion a call tomake_shared
or the ctor ofshared_ptr
combined with the assignment operator is better to read. -
evotion over 9 years@user2882262 I prefer the
make_shared
approach because it improves the readability. It also seams to me that it is the most used approach, despite maybe theshared_ptr<T>(newT())
approach, which can lead to a memory leak as mentioned in an earlier post. I actually read some books and articles aboutshared_ptr
, but it is the first time I see the use ofreset
for assigning ashared_ptr
. If I am honest, I did not new ofreset
before and looked it up. -
evotion over 9 yearsBoth approaches are referenced on cppreference and cplusplus as a method to acquire ownerwhip of an object, so its probably just a preference thing.
-
Barry over 9 yearsThank you @evotion for the detailed description..
-
Barry over 9 yearsThank you, it was explained in detail and its working now
-
Wojtek Surowka over 9 years@user2882262 stackoverflow.com/help/someone-answers
-
Barry over 9 yearsI can't vote up, I do not have enough reputation to vote..
-
Wojtek Surowka over 9 yearsBut I the answers helped you, you should accept one of them
-
ikh over 9 years@evotion I use
reset
because it just makes code more shorter and easy.