[英]How to pass a Smart Pointer in a method without deleting it
I have a program that checks me some tokens, the first time it checks the one with the least HP, the other times it takes one randomly.我有一个程序可以检查我的一些令牌,第一次检查 HP 最少的那个,其他时候随机检查一个。 I thought about transforming this code using the strategy pattern.
我考虑过使用策略模式来转换这段代码。 The code works, but there is a problem: the tokens are cleared
代码有效,但有一个问题:令牌被清除
Token令牌
class Token{
private:
string name;
int hp;
public:
Token(string N, int H){
name=N;
hp=H;
}
string GetName(){
return name;
}
int GetHp(){
return hp;
}
}
Strategy.h策略.h
#ifndef MAIN_CPP_STRATEGY_H
#define MAIN_CPP_STRATEGY_H
#include "Token.h"
class EnemyStrategy{
protected:
std::unique_ptr<Token> token[3];
public:
virtual int Start() = 0;
};
class FirstCase : public EnemyStrategy{
public:
FirstCase(std::unique_ptr<Token> pieces[3]){
for(int i=0; i<3; i++){
token[i] = std::move(pieces[i]);
std::cout<<token[i]->GetName()<<"\n";
}
}
~FirstAttack(){}
int Start() override{
int min=100;
int attacked;
for (int i = 0; i < 3; i++) {
if (token[i]->GetHp() <= min){
min = token[i]->GetHp();
attacked = i;
}
}
return attacked;
}
};
class SecondCase: public EnemyStrategy{
public:
int pawns;
SecondCase(std::unique_ptr<Token> pieces[3]){
for(int i=0; i<3; i++)
token[i] = std::move(pieces[i]);
}
~SecondCase(){}
int Start() override {
int i = rand() % 3;
return i;
}
};
//Controller
class Controller{
EnemyStrategy* strategy;
public:
Controller(EnemyStrategy* tm): strategy(tm){
}
~Controller(){
}
int WhoToAttack(){
return strategy->Start();
}
};
#endif //MAIN_CPP_STRATEGY_H
MainCode主代码
#include "Strategy.h"
#include "Token.h"
int main(){
unique_ptr<Token> token[3];
token[0] = make_unique<Token>("Knight", 20);
token[1] = make_unique<Token>("Mage", 5);
token[2] = make_unique<Token>("Fighter", 10);
Controller* controller;
EnemyStrategy* strategy;
if (control == 0) {
strategy = new FirstAttack(std::move(token));
} else {
strategy = new WarStrategy(std::move(token));
}
controller = new Controller(strategy);
attacked = controller->WhoToAttack();
cout<< "\n the token:" <<attacked; //WORKS
cout<<token[attacked]->GetName(); //DON'T WORKS
delete strategy;
delete controller;
}
My fear is that pointers go out of scope once called in the function, and for this the Strategy pattern works, but the program crashes at: token[attacked]->GetName()
我担心的是,一旦在 function 中调用了来自 scope 的指针 go,并且为此策略模式有效,但程序在以下位置崩溃:
token[attacked]->GetName()
I don't know how to do it, ideas?我不知道该怎么做,想法?
At first I left the unique_ptr smart pointers but then I tried to replace them with shared_ptr, but nothing has changed起初我留下了 unique_ptr 智能指针,但后来我尝试用 shared_ptr 替换它们,但没有任何改变
Here:这里:
if (control == 0) {
strategy = new FirstAttack(std::move(token));
} else {
strategy = new WarStrategy(std::move(token));
}
std::move
doesn't do anything, because arrays are passed by pointer. std::move
不做任何事情,因为 arrays 是通过指针传递的。
The move occurs in the strategy constructor for each element:移动发生在每个元素的策略构造函数中:
FirstCase(std::unique_ptr<Token> pieces[3]){
for(int i=0; i<3; i++){
token[i] = std::move(pieces[i]);
std::cout<<token[i]->GetName()<<"\n";
}
}
After that, you can't use the tokens in main
.之后,您将无法使用
main
中的令牌。
This also happens when using shared_ptr
, but shared_ptr
is copyable and you are not forced to use move
.使用
shared_ptr
时也会发生这种情况,但shared_ptr
是可复制的,您不必强制使用move
。 To use shared_ptr
s, remove the move from the strategy constructor:要使用
shared_ptr
,请从策略构造函数中删除移动:
FirstCase(std::shared_ptr<Token> pieces[3]){
for(int i=0; i<3; i++){
token[i] = pieces[i];
std::cout<<token[i]->GetName()<<"\n";
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.