[英]Trying to understand The behaviour of delete object in int main c++
If I remove either one of the line delete Jim;
如果我删除其中任何一行,请
delete Jim;
or delete DiamondWeapon;
或
delete DiamondWeapon;
it works, but Why?它有效,但为什么? What I meant here is, If I just use
delete DiamondWeapon;
我的意思是,如果我只是使用
delete DiamondWeapon;
it will work but If I also just use delete Jim;
它会工作,但如果我也只使用
delete Jim;
and I remove delete DiamondWeapon;
然后我删除
delete DiamondWeapon;
it will work too.它也会起作用。 I am having hard time wrapping my head around it any help will really be appreciated
我很难将头环绕在它周围,任何帮助都将不胜感激
#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;
}
When you do:当你这样做时:
void Character::SetStrategy(Iweapon* iweaponstrat)
{
delete this->iweapon_Strat;
this->iweapon_Strat = iweaponstrat;
}
Character takes ownership of the pointer.字符拥有指针的所有权。 Your code will handle deletion of the
iweaponstrat
.您的代码将处理
iweaponstrat
删除。 It's not clear if it's by design or accident, but since the delete
is there, we can say that it dos act as an owner.目前还不清楚是有意还是无意,但既然
delete
在那里,我们可以说它确实充当了所有者。
Now, when you do:现在,当你这样做时:
DiamondWeapon = new Axe();
Jim->SetStrategy(DiamondWeapon); // allows deletes DiamondWeapon
Jim->Attack();
delete DiamondWeapon; // deletes DiamondWeapon
You give an Axe
to Jim, giving him ownership and you also delete it yourself.你给了吉姆一把
Axe
,给了他所有权,你也自己删除了它。 This is asking for trouble, which eventually occurs.这是自找麻烦,最终会发生。
You have two paths from here:从这里你有两条路径:
shared_ptr
or unique_ptr
, strongly recommended.shared_ptr
或unique_ptr
。The problem you have is multiple copies of the same pointer value.您遇到的问题是同一指针值的多个副本。
When you当你
delete DiamondWeapon;
delete Jim;
The destructor ~Character
tries to delete the object that DiamondWeapon
also pointed to.析构函数
~Character
试图删除DiamondWeapon
也指向的对象。 This is incorrect C++, and your program's behaviour is undefined.这是不正确的 C++,并且您的程序的行为未定义。
Rather than passing around raw ( *
) pointers, you should use std::unique_ptr
, so that you know there is only ever one pointer pointing to each Weapon
and Character
您应该使用
std::unique_ptr
,而不是传递原始 ( *
) 指针,以便您知道只有一个指针指向每个Weapon
和Character
class Character // its Context as per UML diagram
{
private:
std::unique_ptr<Iweapon> iweapon_Strat;
public:
Character(std::unique_ptr<Iweapon> iweaponStrat) :iweapon_Strat(iweaponStrat) {}
void SetStrategy(std::unique_ptr<Iweapon> iweaponstrat)
{
iweapon_Strat = iweaponstrat;
}
void Attack() const
{
iweapon_Strat->Use();
}
};
Then you will have a compile time error when you hold extra pointers.那么当您持有额外的指针时,您将遇到编译时错误。 As a bonus, your dynamic-storage-duration ("Heap") objects are cleaned up when the scope defining the pointer ends.
作为奖励,当定义指针的范围结束时,您的动态存储持续时间(“堆”)对象将被清除。
int main()
{
//this work
{
auto Mike = std::make_unique<Character>(std::make_unique<Sword>());
Mike->Attack();
Mike = std::make_unique<Character>(std::make_unique<Axe>());
Mike->Attack();
}
//this work too
{
auto Ryan = std::make_unique<Character>Character();
std::unique_ptr<Iweapon> SilverWeapon;
SilverWeapon = std::make_unique<Sword>();
// Ryan->SetStrategy(SilverWeapon); // Error, can't copy SilverWeapon
Ryan->SetStrategy(std::move(SilverWeapon)); // SilverWeapon is now null
Ryan->Attack();
SilverWeapon = std::make_unique<Axe>();
// Ryan->SetStrategy(SilverWeapon); // Error, can't copy SilverWeapon
Ryan->SetStrategy(std::move(SilverWeapon)); // SilverWeapon is now null
Ryan->Attack();
}
{
std::unique_ptr<Iweapon> DiamondWeapon = std::make_unique<Sword>();
auto Jim = std::make_unique<Character>Character();
DiamondWeapon = std::make_unique<Sword>();
// Jim->SetStrategy(DiamondWeapon); // Error, can't copy DiamondWeapon
Jim->SetStrategy(std::move(DiamondWeapon)); // DiamondWeapon is now null
Jim->Attack();
DiamondWeapon = std::make_unique<Axe>();
// Jim->SetStrategy(DiamondWeapon); // Error, can't copy DiamondWeapon
Jim->SetStrategy(std::move(DiamondWeapon)); // DiamondWeapon is now null
Jim->Attack();
}
{
std::unique_ptr<Iweapon> WoodenWepon = std::make_unique<Sword>();
Character Kim;
// Kim.SetStrategy(WoodenWepon); // Error, can't copy WoodenWeapon
Kim.SetStrategy(std::move(WoodenWepon)); // WoodenWeapon is now null
Kim.Attack();
WoodenWepon = std::make_unique<Axe>();
// Kim.SetStrategy(WoodenWepon); // Error, can't copy WoodenWeapon
Kim.SetStrategy(std::move(WoodenWepon)); // WoodenWeapon is now null
Kim.Attack();
}
// etc.
//following is just for system pause
std::string end;
std::cin >> end;
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.