如何在没有显式设置的情况下使对象指针为NULL,而不显式删除和没有静态函数?

时间:2010-08-18 06:42:54

标签: c++

我正在开发一个c ++应用程序。   在我的代码中,我有一个对象指针       TestClass * pObj = new TestClass();   和成员函数调用像pObj-> close();   在close()成员函数内部,我应该将pObj设为NULL。   根据我们的要求,TestClass用户不应该在pObj上调用delete。(TestClass的析构函数是专门为此目的而私有的)  此外,TestClass不应公开任何静态方法来接收指针并使其为NULL。

有没有其他方法可以在调用close()后将pObj设为NULL?

我试过一种方法。  在close()函数内部,我使用const_cast删除了此指针的constness。  并参考了它。  然后我做了这个= NULL。  即使再调用一边,pObj指针值仍然存在。它没有设置为NULL。  这可能是由于该指针的地址和pObj的地址不同。  请帮助。

编辑:对不起,我错过了什么。在一个名为init的静态函数中调用new。 init函数如下所示。 void init(TestClass *& pObj);因此,TestClass用户首先调用init进行分配。但他不能叫deinit(不应该有任何这样的功能)实际上,这不是我的设计。我进入这个项目时就出现了:(

9 个答案:

答案 0 :(得分:10)

想象一下这样的代码:

TestClass *ptr1 = new TestClass();
TestClass *ptr2 = ptr1;
ptr2->close();

您希望将哪个指针设置为null?在close方法内部,您无法获知有多少指针指向您的对象以及如何访问close方法。

答案 1 :(得分:8)

鉴于你的约束,没有办法做你想做的事。

一个警告:如果您的类的用户在堆栈上的对象上创建会发生什么:TestClass test;

还有一个问题,为什么你希望你的班级用户被迫拨打new来分配你班级的对象,然后禁止拨打delete。对我毫无意义。

答案 2 :(得分:4)

  

根据我们的要求,TestClass用户不应该在pObj上调用delete。(TestClass的析构函数是故意为此目的而私有的)另外,TestClass不应该暴露任何静态方法来接收指针并使其为NULL。

谁设定了这些要求?对于他们每个人,问“为什么?”。他们似乎绝对武断,没有任何意义。

  

和成员函数调用如pObj-> close();在close()成员函数内部,我应该将pObj设为NULL。

再次,“为什么?”。忽略从函数内部改变它是不可能的,使用这样的风格是疯狂的。正常的C ++方式是破坏对象。

如果你的“为什么”得不到合理的答案,你应该考虑辞掉这份工作,或者准备好在挫折中度过你的时间。你提出的设计“要求”非常疯狂。

答案 3 :(得分:4)

疯狂的问题需要一个疯狂的解决方案,所以这里有一个。你不能完全按照自己的意愿去做,因为跟踪对象的原始指针是不可能的。但是,如果使用某种智能指针,则可以在销毁对象时跟踪它们并使其无效。这是在较少疯狂情况下的常见要求,因此已经有智能指针来执行此操作:shared_ptr以保持对象存活,并weak_ptr跟踪对象并在其被销毁时变为空。所以解决方案看起来像这样:

class TestClass
{
public:
    static weak_ptr<TestClass> create()
    {
        shared_ptr<TestClass> shared(new TestClass);
        shared->self = shared;
        return shared;
    }

    void close()
    {
        self.reset();
    }

private:
    shared_ptr<TestClass> self;
};

int main()
{
    weak_ptr<TestClass> object = TestClass::create();
    weak_ptr<TestClass> copy = object;

    assert(!object.expired());
    assert(!copy.expired());

    object.lock()->close();

    assert(object.expired());
    assert(copy.expired());
}

答案 4 :(得分:3)

没有。请考虑以下代码:

TestClass * const pObj = new TestClass();
pObj->close();

编译器将拒绝代码,即使close为const。指针是const,但不是新的TestClass对象。因此,您可以通过指针调用非const方法,但是您无法更改指针本身。这意味着你也不能将它设置为NULL。

答案 5 :(得分:2)

它基本上意味着您需要将this指针设置为NULL。据我所知,这是不可能的。如果它有帮助你可以认为调用方法按值this指针,即你在方法中做的任何改变都不会反映在外面。

答案 6 :(得分:2)

当你编写可怕的代码时,你可以在从close()返回之前添加一些内联汇编和xor ecx,ecx

答案 7 :(得分:2)

除非你碰巧对pObj init过于谨慎,否则可能无法正常工作。

#include <map>

std::map<TestClass*, TestClass**> pointers();

void init(TestClass *& pObj)
{
   pObj = new TestClass();
   pointers[pObj] = &pObj;
}

void TestClass::Close()
{
    *pointers[this] = null;
    pointers.erase(this);
    delete this;
}

答案 8 :(得分:0)

虽然它充满了危险,但可能是一种方式

TestClass::Close(Testclass *&p){
   p = NULL;
}

pObj->close(pObj);

编辑:解释限制Close();

pObj是否可以在'TestClass :: Close'的范围内访问?例如命名空间范围变量? 如果是,TestClass :: Close方法可以简单地设置pObj = NULL;

如果不是,恕我直言