首页 > 解决方案 > 试图理解 int main c++ 中删除对象的行为

问题描述

如果我删除其中一条线delete Jim;或者delete DiamondWeapon;它可以工作,但是为什么?我的意思是,如果我只是使用delete DiamondWeapon;它会起作用,但如果我也只是使用delete Jim;并且我删除delete DiamondWeapon;它也会起作用。我很难理解它,任何帮助都将不胜感激

#include<iostream>
#include<string>

// Strategy pattern IBehaviour (Iweapon)
// Context Character ( will access this.strategy_.Function() ) ( his.strategy will be Iweapon )
// Concrete Strategies ( Each weapon will have a unique Algorithms for each weapon ).


class Iweapon // ( interface Ibehaviour strategy )
{
public:
    virtual ~Iweapon() { }
    virtual void Use() const = 0; /* Search Results Featured snippet from the web
                                    The const member functions are the functions which are declared as constant in the program.
                                    The object called by these functions cannot be modified.It is recommended
                                    to use const keyword so that accidental changes to object are avoided.A const member function can be called by any type of object.*/
};

class Character // its Context as per UML diagram
{
private:
    Iweapon* iweapon_Strat;
public:
    Character(Iweapon* iweaponStrat = nullptr) :iweapon_Strat(iweaponStrat) { }
    /*{
        this->iweapon_Strat = iweaponStrat;
    }*/
    ~Character() {
        delete  this->iweapon_Strat;
    }

    void SetStrategy(Iweapon* iweaponstrat) {
        delete this->iweapon_Strat;
        this->iweapon_Strat = iweaponstrat;
    }

    void Attack() const //DoSomeLogic() 
    {
        this->iweapon_Strat->Use();
    }
};

// following are ConcreteStrategies(A,B,C ... ) 

class Sword :public Iweapon {
public:
    void Use() const override {
        std::cout << "\n\nSword is Attacking\n\n";
    }
};

class Axe : public Iweapon {
public:
    void Use() const override {
        std::cout << "\n\nAxe is Attacking\n\n";
    }
};

int main() {
    //this work
    {
        Character* Mike = new Character(new Sword);
        Mike->Attack();
        Mike = new Character(new Axe);
        Mike->Attack();

        delete Mike;
    }
    //this work too
    {

        Character* Ryan = new Character();
        Iweapon* SilverWeapon = NULL;

        SilverWeapon = new Sword;
        Ryan->SetStrategy(SilverWeapon);
        Ryan->Attack();

        SilverWeapon = new Axe;
        Ryan->SetStrategy(SilverWeapon);
        Ryan->Attack();

        delete Ryan;
    }
    //this doesn't work but if I remove either one of the line *** delete Jim; *** or *** delete DiamondWeapon; *** it work, But Why
    // i meant here is : Alone if I just have delete DiamondWeapon; it will work
    // but if Alone i also just have delete Jim; and I remove delete DiamondWeapon; it will work too.
    //I am having hard time wraping my head around it any help will really be appreciated
    {
        Iweapon* DiamondWeapon = new Sword();
        Character* Jim = new Character();

        DiamondWeapon = new Sword();
        Jim->SetStrategy(DiamondWeapon);
        Jim->Attack();

        DiamondWeapon = new Axe();
        Jim->SetStrategy(DiamondWeapon);
        Jim->Attack();

        delete DiamondWeapon;
        delete Jim;
    }
    //This also doesn't work
    {
        Iweapon* WoodenWepon = new Sword();
        Character Kim;

        //WoodenWepon = new Sword();
        Kim.SetStrategy(WoodenWepon);
        Kim.Attack();

        WoodenWepon = new Axe();
        Kim.SetStrategy(WoodenWepon);
        Kim.Attack();

        delete WoodenWepon;
        //delete Kim;
    }
    //this Work
    {
        Character* Denzel = new Character();
        Iweapon* weapon = new Sword;
        Denzel->SetStrategy(weapon);
        Denzel->Attack();

        Denzel->SetStrategy(new Axe);
        Denzel->Attack();

        //delete weapon;
        delete Denzel;
    }
    // This also work
    {
        Iweapon* GoldWeapon = NULL;
        Character* Jhon = new Character();

        GoldWeapon = new Sword;
        Jhon->SetStrategy(GoldWeapon);
        Jhon->Attack();

        GoldWeapon = new Axe;
        Jhon->SetStrategy(GoldWeapon);
        Jhon->Attack();

        delete GoldWeapon;
        //delete Jhon;
    }


    //following is just for system pause
    std::string end;
    std::cin >> end;
    return 0;
}

标签: c++classdestructor

解决方案


当你这样做时:

void Character::SetStrategy(Iweapon* iweaponstrat) 
{
    delete this->iweapon_Strat;
    this->iweapon_Strat = iweaponstrat;
}

字符获取指针的所有权。您的代码将处理删除iweaponstrat. 目前尚不清楚这是设计还是意外,但既然delete存在,我们可以说它确实充当了所有者。

现在,当你这样做时:

DiamondWeapon = new Axe();
Jim->SetStrategy(DiamondWeapon); // allows deletes DiamondWeapon
Jim->Attack();

delete DiamondWeapon; // deletes DiamondWeapon

你给Axe吉姆一个,给他所有权,你也自己删除它。这是自找麻烦,最终会发生。

从这里你有两条路:

  • 使用shared_ptror unique_ptr,强烈推荐。
  • 定义明确的所有权,尊重它,并且只删除拥有的对象。很难拉下来。C 程序员必须一直处理这个问题,它节省了智能指针的开销,但在你的水平上真的不值得付出努力。

推荐阅读