C++ 使用';这';指向删除的指针
我正在为学校做一个项目。 它模拟学生从自动售货机购买苏打水。 有一个叫做Card的班级,它是班级学生中的一员。 就是 每个学生都有一张卡片,这很有意义C++ 使用';这';指向删除的指针,c++,this,delete-operator,C++,This,Delete Operator,我正在为学校做一个项目。 它模拟学生从自动售货机购买苏打水。 有一个叫做Card的班级,它是班级学生中的一员。 就是 每个学生都有一张卡片,这很有意义 class Student { public: Student( Office &cardOffice ); ~Student(); bool action(); private: Office* studentOffice; // stores cardoffice. C
class Student {
public:
Student( Office &cardOffice );
~Student();
bool action();
private:
Office* studentOffice; // stores cardoffice.
Card* card; // stores card
};
学生卡是通过调用studentOffice.create()函数创建的。该函数返回一张卡片
Card* Office::create( int id, int money ) {
Card* card = new Card();
card->id = id;
card->amount = money;
return card;
}
学生在VendingMachine类中调用名为action()的函数来购买食物。VendingMachine中的buy函数从VendingMachine类中的状态枚举返回类型枚举
有一个prng,从0到9生成一个随机数。作业上说,学生卡被毁的几率为十分之一。下次调用student.action()时,他/她将获得一个新的
VendingMachine::Status VendingMachine::buy(Card* &card)
{
if(prng(9) == 0) // generates number from 0-9
{
delete card;
}
return status;
}
最初,我想检查student的action()例程,查看卡片是否为空(如果已删除),如果出现这种情况,则创建一个新卡片。但是,我知道该代码会到达删除卡部分,但在检查该卡是否为空时失败。这意味着卡不是空的,这意味着删除无效
但我也注意到传递的卡片是
Card* &card
我当时正在考虑使用一个带有“this”指针的调用,因为我知道这个学生就是所谓的这个例程,“this”将指向调用它的对象,根据:
它指向为其调用成员函数的对象。
从
但是,如果我这样做:
if(prng(9) == 0)
{
delete this->card;
}
在运行makefile时,会出现以下错误:
错误:类VendingMachine没有名为card的成员
但事实并非如此。编译器是否假设自动售货机将调用此方法?因为学生是这样做的
if(prng(9) == 0)
{
cout << "Destroying card" << endl;
delete card;
card = NULL;
cout << "Card Destroyed" << endl;
}
if(prng(9)==0)
{
cout在方法buy
中,您应该删除指针并将其设置为NULL
(delete
不会自动将指针设置为NULL
):
这就是指针通过引用传递的原因(因此您可以将NULL
分配给原始指针,而不是它的副本)
除此之外,这张->卡
不会编译,因为卡
属于类学生
,而不是自动售货机
。从自动售货机
的角度来看,它只是方法购买
中的一个参数,当你调用删除
时,没有什么可以说你调用的指针将其设置为NULL
。如果要确保删除后它为NULL,则应在删除后自己执行此操作。除了@betabando的答案外,您还可以在宏中定义一个delete方法来执行此操作
#define DELETE(ptr) ( delete ptr; ptr = NULL;)
尽管不可否认,这几乎总是一个坏主意,尤其是当你在学校时,你应该养成在删除指针后将其设置回NULL的习惯
此外,这可能会让你产生错误的安全感:
void MethodDeleteThis(void* item)
{
delete item;
item = NULL;
}
无法真正解决此问题,因为item是传递的任何指针的副本。因此,虽然delete可能已释放item指向的对象,但将指针设置为NULL不会将传递给方法的指针的值更改为NULL。唯一的解决方法是使用双指针或通过引用传递指针这看起来很奇怪,也不合适。不过我见过gobject和gstreamer这样做
我注意到,如果有任何分配或解除分配,许多库都会返回指针,以便您可以更可靠地检索和测试值。正如其他人所指出的,任何时候您删除
指针时,您也应该立即将其设置为NULL
。不要使用宏,养成doi的习惯把这个给我
现在,尝试戴上我的最佳实践帽:
我总是发现在做这种事情时传递双指针比通过引用传递指针更有用:
VendingMachine::Status VendingMachine::buy(Card** card) {
// ...
if (NULL == *card) {
delete *card;
*card = NULL;
}
这迫使您在代码中对指针有点不同的处理方式,但好处是,更明显的是您在操作指针,并且消除了方法调用中的歧义:
vend.buy(card); // Pointer reference
vend.buy(&card); // Pointer to pointer
使用第二个调用,您只需查看它,该方法可以并且可能会修改<代码>卡的值。
调用<代码>删除>代码>不会使指针为空。这需要明确地进行。您可能想考虑“销毁”。标记,而不是删除卡片对象。这将防止加载if NULL
测试和需要传递指针引用。@Roddy:我认为这项作业的要点之一是教学生如何正确传递指针引用。@Justinᚅᚔᚈᚄᚒᚔ 我们得到了赋值的结构。也就是说,我们可以拥有的函数,等等。传入是赋值,我们不允许更改它。:)最好不要使用指针。传递一个卡片值而不是卡片指针
。指针没有所有权语义,因此它是nOT清除谁负责删除它们,因此不使用(原始的那样)在现代C++中很多。当你有一个指针时,它通常被包裹在智能指针内。但是这个例子很简单,你甚至不需要指针。我会试试。非常感谢。什么是T?
VendingMachine::Status VendingMachine::buy(Card** card) {
// ...
if (NULL == *card) {
delete *card;
*card = NULL;
}
vend.buy(card); // Pointer reference
vend.buy(&card); // Pointer to pointer