开发者

How to make object pointer NULL without setting it explicitly, without deleting explicitly and without static functions?

开发者 https://www.devze.com 2023-01-11 20:45 出处:网络
I am working on a c++ application. In my code i have an object pointer like TestClass *pObj = new TestClass();

I am working on a c++ application. In my code i have an object pointer like TestClass *pObj = new TestClass(); and Member function call like pObj->close(); Inside close() member function, i should make pObj to NULL. As per our requirement, TestClass users should not call delete on pObj.(Destructor of TestClass is made private intentionally for this purpose) Also, TestClass should not expose any static method to receive a pointer and making it NULL.

Is there any other way to make pObj to NULL once close() is called ?

I tried one way. Inside close() function, i removed constness for this pointer using const_cast. and took a reference of it. Then i made this = NULL. Even then calling side, pObj pointer value remains. It is not getting set to NULL. It may be due to the Address of this pointer and Address of pObj are different. Pls help.

EDIT: Sorry, i missed something. new is getting called inside a static function called init. init function is like below. void init(TestClass *& pObj); So TestClass user calls init first for allocation. But he can't call deinit(there should not be any such function) Actually, this is not my design. It was present when i e开发者_开发知识库ntered this project :(


Imagine such code:

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

Which pointer do you want to be set to null? Inside close method you have no information how many pointers point to your object and how is close method accessed.


There's no way of doing what you want, given your constraints.

One warning: what happens if the user of your class creates on object on the stack: TestClass test;?

One question more, why do you want the users of your class being forced to call new to allocate objects of your class, but then being forbid to call delete. Makes no sense to me.


An insane problem requires an insane solution, so here is one. You can't do exactly what you want, since it's impossible to keep track of the raw pointers to your object. However, if you use some kind of smart pointer, then they can be tracked and nullified when the object is destroyed. This is a common requirement in less insane circumstances, so there are already smart pointers to do this: shared_ptr to keep the object alive, and weak_ptr to track the object and go null when it's destroyed. So the solution would look something like this:

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());
}


As per our requirement, TestClass users should not call delete on pObj.(Destructor of TestClass is made private intentionally for this purpose) Also, TestClass should not expose any static method to receive a pointer and making it NULL.

Who set those requirements? For each of them, ask "Why?". They seem absolutely arbitrary, they make no sense.

and Member function call like pObj->close(); Inside close() member function, i should make pObj to NULL.

Again, "Why?". Disregarding changing this from inside of a function is not possible, using such style is crazy. A normal C++ way is to destruct the object instead.

If you will get no reasonable answer to your "whys", you should probably consider quitting the job, or prepare to spend your time there in frustration. The design "requirements" you have presented are really extraordinary crazy.


No. Consider the following code:

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

The compiler will not reject the code, even if close would be const. The pointer is const, but not the new TestClass object. Therefore you can call non-const methods via the pointer, but you can't change the pointer itself. That means you can't set it to NULL either.


It basically means that you need to set this pointer to NULL. This is not possible as far as I know. If it helps you can think the calling of the method taking this pointer by value i.e. whatever change you do inside the method will not be reflected outside.


while you're writing terrible code you may as well add some inline assembly and xor ecx,ecx just before you return from close().


Probably won't work unless you happen to be super careful with the pObj init returns to not to anything fancy with it.

#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;
}


Though, it is full of dangers, a way could be

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

pObj->close(pObj);

EDIT: After explanation on restriction of Close();

Is pObj accessible in scope of 'TestClass::Close'? e.g. a namespace scope variable? If yes, the TestClass::Close method can simply set pObj = NULL;

If no, there is no way IMHO

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号