|
hey vik, seriously, why do you want to use a constructor to destruct the object ?
don't you think this kind of action is inapropriate for a constructor ?
TOXCCT >>> GEII power
[VisualCalc 3.0 updated ][Flags Beginner's Guide new! ]
|
|
|
|
|
Dude, you you need to do that for? Just a quick sily question ...
|
|
|
|
|
Really I don't know why I asked this question
But consider a situation where I am taking some argument in constructor and depending upon this I want "control" over object creation.
I know there are other way to do it.
But can we use such nasty code?
|
|
|
|
|
yes, it will work.
the only strange bit is that your variable "object" will receive the value that it would have received even if you didn't delete the object, however (ie. not NULL). it will look like a valid pointer, but the memory it pointed to will have been freed by the delete.
more[^]
Cleek | Image Toolkits | Thumbnail maker
|
|
|
|
|
Chris Losinger wrote: yes, it will work.
It will not 'work'. The object is not fully constructed so its destructor cannot be called. At best, the code represents undefined behavior.
|
|
|
|
|
Roland Pibinger wrote: It will not 'work'.
of course it will. step through the code in a debugger and see what happens.
memory is allocated in 'new', then the ctor is called. 'delete' is called, which releases the memory allocated by new. since there are no instructions after the delete, the ctor exits and that's it - no uninitialized members are touched, nothing is unconstructed.
there is certainly potential for dangerous behavior here, ad there's definitely a better way to do whatever the OP is trying to do. but as written, this is safe.
Roland Pibinger wrote: The object is not fully constructed so its destructor cannot be called
that statement is not true in all situations
Cleek | Image Toolkits | Thumbnail maker
|
|
|
|
|
Chris Losinger wrote: memory is allocated in 'new', then the ctor is called. 'delete' is called, which releases the memory allocated by new
I haven't tried the code, but it will change the behaviour of the new operator which may return a pointer to the deleted object instead of NULL.
I assume the code will "work" in the aspect of performing a delete on the constructed object, but the returned pointer from new cannot be trusted; the object may have been deleted and if used will cause an access violation.
I suggest overriding the new operator instead.
It's supposed to be hard, otherwise anybody could do it!
Regarding CodeProject: "resistance is pointless; you will be assimilated"
|
|
|
|
|
Roger Stoltz wrote: but it will change the behaviour of the new operator which may return a pointer to the deleted object instead of NULL.
yes, as i noted in my first reply.
it's not good programming practice in general, and i can't think of a single situation where this is the best solution. but, as written, (as an academic question), it appears safe.
i've spent a bit of time this AM looking over the web for someone who can definitively show that it (as written in the OP) isn't safe - haven't found one yet. a lot of people have asked this question, and the discussions all agree that it's safe as long as you pay attention to things like virtual dtors, derived classes, no stack allocation of the object, don't trust the return from new, etc..
Cleek | Image Toolkits | Thumbnail maker
|
|
|
|
|
Chris Losinger wrote: as i noted in my first reply
Sorry Chris, didn't pay enough attention.
Chris Losinger wrote: looking over the web for someone who can definitively show that it (as written in the OP) isn't safe - haven't found one yet
I think you can stop looking.
IMO it's quite clear what happens, the same way you described it previously.
Whether it's "safe" or not depends on how we define "safe"; It will run and the behaviour is predictable and in that aspect it's considered safe. But it has to be used with certain restrictions, otherwise it's not safe.
Better safe than sorry...;)
--
Roger
It's supposed to be hard, otherwise anybody could do it!
Regarding CodeProject: "resistance is pointless; you will be assimilated"
|
|
|
|
|
Roger Stoltz wrote: Sorry Chris, didn't pay enough attention
and i probably wasn't as clear about what i was saying as i should have been.
Roger Stoltz wrote: But it has to be used with certain restrictions, otherwise it's not safe.
if i was in charge of writing coding standards for my company (oh wait, i am!), those restrictions would be simple: never do this.
Cleek | Image Toolkits | Thumbnail maker
|
|
|
|
|
Chris Losinger wrote: never do this
Ahh, the good old KISS!
Well, I'm off now; have a nice weekend.
It's supposed to be hard, otherwise anybody could do it!
Regarding CodeProject: "resistance is pointless; you will be assimilated"
|
|
|
|
|
Chris Losinger wrote: of course it will. step through the code in a debugger and see what happens.
Hmmm, works with g++ under Linux as well.
However, I am not sure what would other compilers do.
My programming blahblahblah blog. If you ever find anything useful here, please let me know to remove it.
|
|
|
|
|
Hi,
in the specific case presented there 'should' be no problem.
BUT, I don't think it safe to do this when using virtual destructors.
Because the this pointer isn't fully valid for all dervided class
functionality like the derived destructor, which could be triggered
when calling delete this;
See this article[^] for more info.
codito ergo sum
|
|
|
|
|
BadKarma wrote: BUT, I don't think it safe to do this when using virtual destructors
have you noticed that he does delete this in the Constructor ?
TOXCCT >>> GEII power
[VisualCalc 3.0 updated ][Flags Beginner's Guide new! ]
|
|
|
|
|
toxcct wrote: have you noticed that he does delete this in the Constructor ?
If the class used inheritence, it is possible to get to a point where all the constructors in the inheritence chain would not have been called yet. Thus, calling the virtual destructors would lead to possible memory issues. That is what he was getting at.
As a side note, the code written in the original post should NEVER be used in any real code. Use a constructor for what it is meant for; the same goes for destructors. Making these functions do things contrary to general practice serves no purpose.
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
Zac
|
|
|
|
|
Zac Howland wrote: As a side note, the code written in the original post should NEVER be used in any real code. Use a constructor for what it is meant for; the same goes for destructors. Making these functions do things contrary to general practice serves no purpose.
Absolutely.
Otherwise the code be hard to use, maintain and even understand.
What should be done in this case, since the OP wants to gain control over objects created on the heap, is to override the new operator.
--
Roger
It's supposed to be hard, otherwise anybody could do it!
Regarding CodeProject: "resistance is pointless; you will be assimilated"
|
|
|
|
|
a simpler/better solution would be to make the constructor protected or private and use the Factory Pattern to create an object if the correct params are given, otherwise just return NULL.
In this case the programmer has a mean to validate if the construction of the object worked
codito ergo sum
|
|
|
|
|
BadKarma wrote: make the constructor protected or private and use the Factory Pattern
Could be. I was thinking about the factory pattern, but the OP said that would always be using new to create the objects. That's why I suggested overriding the new operator.
As always, there's more than one solution to a problem and I took the question as hypothetical.
It's supposed to be hard, otherwise anybody could do it!
Regarding CodeProject: "resistance is pointless; you will be assimilated"
|
|
|
|
|
Roger Stoltz wrote: Could be. I was thinking about the factory pattern, but the OP said that would always be using new to create the objects. That's why I suggested overriding the new operator.
My recommendation (instead of overriding the new/delete operators) would be to use a smart pointer (since it appears he wants it to self-destruct):
class MyClass<br />
{<br />
MyClass() { cout << "I got created!" << endl; }<br />
~MyClass() { cout << "I got destroyed!" << endl; }<br />
};<br />
<br />
void main()<br />
{<br />
shared_ptr<MyClass> pClass(new MyClass);<br />
}
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
Zac
|
|
|
|
|
Zac Howland wrote: If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
couldn't be more correct;P
codito ergo sum
|
|
|
|
|
I'm trying to compile my old application in VS2005.
But the compiler no longer accepts the default assignment of NULL to a vector iterator. How do I resolve this?
I declare my function like this:
vector<CSomeClass*>::iterator MyFunction(vector<CSomeClass*>::iterator itStartPos = NULL);
The compiler says:
error C2440: 'default argument' : cannot convert from 'int' to 'std::_Vector_iterator<_Ty,_Alloc>'
I can't default the parameter to myVectorList.begin() because the function declaration is not aware of which list the iterator belongs.
Thanks
--
The Obliterator
-- modified at 7:40 Friday 2nd June, 2006
|
|
|
|
|
Obliterator wrote: function declaration is not aware of which list the iterator belongs.
does the function itself know ? if not, how do you know the iterator is valid ? (can't test against vec.end() if you don't have the vector)
a quick run through Google tells me that it's not possible, in general, to set iterators to NULL. iterators are not pointers, for one thing.
i think you'll need to re-work that function a bit
Cleek | Image Toolkits | Thumbnail maker
|
|
|
|
|
Good point. Actually, I simplified the function declaration for the purposes of the queston. The end vector is also supplied as a parameter to the function.
However, the function is indeed aware of the list and simply defaults to the beginning of the list if itStartPos parameter is NULL.
I guess your right - I'm going to have to drop the default parameter here and update each call to the function. Serves me right for using a hack to assign NULL to it in the first place. Damn this new strict checking!!!
Thanks for your response. Much appreciated.
--
The Obliterator
|
|
|
|
|
Starting with VC7, STL iterators were type-checked better. You can't treat a collection<T>::iterator as a T* (or any other pointer value, like NULL).
--Mike--
Visual C++ MVP
LINKS~! Ericahist | PimpFish | CP SearchBar v3.0 | C++ Forum FAQ
|
|
|
|
|
So I see. This is causing me some real headaches!!!
Is there no assignement that can be made to the iterator which means its invalid?
I used to assign NULL to iterators to mean they wern't being used.
Then I could simply check its NULL status and act accordingly.
There must be a way of saying an iterator is invalid.
If I assign it the value of vectorlist.end() I could test against that - but does initial end assignment remain valid after things are added to the vector list?
--
The Obliterator
|
|
|
|