如何在不删除的情况下在方法中传递智能指针



我有一个程序,它会检查我一些令牌,第一次检查HP最少的令牌,其他时候随机抽取一个。我考虑过使用策略模式转换此代码。代码有效,但有一个问题:令牌被清除

代币

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;
}
}

策略.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

主代码

#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;
}

我担心的是,一旦在函数中调用指针,指针就会超出范围,因此策略模式可以工作,但程序在以下位置崩溃:token[attacked]->GetName()

我不知道怎么做,想法?

起初,我留下了unique_ptr智能指针,但后来我试图用shared_ptr替换它们,但没有任何变化

此处:

if (control == 0) {
strategy = new FirstAttack(std::move(token));
} else {
strategy = new WarStrategy(std::move(token));
}

std::move什么都不做,因为数组是通过指针传递的。

移动发生在每个元素的策略构造函数中:

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";
}
}

之后,就不能使用main中的令牌了。

使用shared_ptr时也会发生这种情况,但shared_ptr是可复制的,您不必强制使用move。要使用shared_ptrs,请从策略构造函数中删除移动:

FirstCase(std::shared_ptr<Token> pieces[3]){
for(int i=0; i<3; i++){
token[i] = pieces[i];
std::cout<<token[i]->GetName()<<"n";
}
}

最新更新