1

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 entered this project :(

4
  • 15
    Terrible design, in my opinion. Also this is an rvalue, you'll never change it. Commented Aug 18, 2010 at 6:50
  • 1
    This is, without a doubt, the worst homework assignment I've ever seen. Commented Aug 18, 2010 at 8:05
  • 1
    What is this? A puzzle homework? The requirements sound crazy, they make not sense at all. Commented Aug 18, 2010 at 8:21
  • "Hey, guys, let's write this in C++. C++ has destructors and smart pointers and things like that, but since we're manly, we're going to make the destructor private, and then implement a different method that will do what the destructor would have done in the first place. Isn't this the coolest idea you've ever heard? Oh, and you won't be able to make the objects on the stack." Commented Mar 23, 2011 at 9:53

9 Answers 9

10

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.

Sign up to request clarification or add additional context in comments.

Comments

8

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.

2 Comments

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 entered this project :(
This init function breaks your own constraints as it must be a static member function (or free function), I guess. You have close to be defined the same way: as a static member function or as a free function. In essence you have to use the same paradigm upon creating and deleting things.
4

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

Comments

4

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.

2 Comments

Hi Suma, Myself not happy with design made by other guys. I don't have permission to change the design. So i am sorry, if u feel its a stupid question.
Do you have "a permission" to ask other guys "Why"? The "requirements" make an easy and ordinary task difficult or perhaps even impossible.
3

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.

Comments

2

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.

1 Comment

You could set this to null, since it's a copy of the address though that would not do much...
2

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

Comments

2

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

1 Comment

+1, even if this will only solve the problem if user code does not copy the pointer and then calls close with the copy.
0

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

2 Comments

Actually, close() should not receive any parameters.
pObj is not accessible in TestClass::close(). I too think that there is no way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.