简体   繁体   English

如何在方法中传递智能指针而不删除它

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM