[bt-devel] Programming Techniques
Joachim Ansorg
bt-devel@crosswire.org
Fri, 8 Mar 2002 17:08:27 +0100
Hi David!
Welcome on bt-devel!
> {
> Object* ob = new Object();
> ...do stuff with ob....
> delete ob;
> }
> now, firstly, if possible ob should not be allocated on the heap like
> that, it should be allocated on the stack, as in:
>
> {
> Object ob;
> ...do stuff with ob...
> }
>
> this is because it is quicker (heap allocations are slow, stack
> allocations are fast), easier to read, less code, and there is no hope
> of there being a memory leak.
At least I know that we should allocate on the stack, because we can't forget
to delete the object :)
But often we have code like
CSwordKey* key = CSwordKey::createInstance(module);
Is there a way to do this on the stack?
And at the moment we use much code like
CSwordVerseKey* vk = dynamic_cast<CSwordVerseKey*>(
CSwordKey::createInstance(module) );
Is there a way to get rid of the cast? Sorry for asking all these (probably
dumb) questions, but I don't know C++ well enough.
> BibleTime uses the new operator, to start with, and the C++ standard
> says that if new fails, it will throw an exception. It's just about
> impossible to program in C++ without touching exceptions. Even if you
> could get around the exception problem, you would still have problem 1,
> which is that this is difficult to maintain, because you have to
> remember to delete ob.
AFAIK Qt overloads the new operator, but I'm not sure about this. And I never
used exceptions, so I can't judge about this :)
> struct close_file { void operator()(int fd) const { close(fd); } };
>
> {
> scoped_resource<int,close_file> file(open("file.txt",O_RDONLY));
> ...use file...
> } //file is automatically closed
>
> I understand this might be all quite confusing, but once you understand
> it it's really cool. Please let me know if you don't understand
> anything.
We do at almost all places use QFile on the stack, which closes itself (I
hope :)
While converting some of the code I run into trouble (function
CPrintItem::moduleText):
CSwordKey* startKey = CSwordKey::createInstance(m_module);
CSwordKey* stopKey = CSwordKey::createInstance(m_module);
if (.. left out here ..) {
CSwordVerseKey* vk_start = dynamic_cast<CSwordVerseKey*>(startKey);
CSwordVerseKey* vk_stop = dynamic_cast<CSwordVerseKey*>(stopKey);
}
delete startKey;
delete stopKey;
If I use
util::scoped_ptr<CSwordKey> startKey( CSwordKey::createInstance(m_module) );
util::scoped_ptr<CSwordKey> stopKey( CSwordKey::createInstance(m_module) );
the casts
CSwordVerseKey* vk_start = dynamic_cast<CSwordVerseKey*>(startKey);
won't work. Is the casting inelegant C++? Any way to make this work with
scoped_ptr?
Maybe this is related to the comments at the beginning of this mail.
One last question: How do we manage things if the deklaration of a member is
in the header file and the new statement is in the .cpp file? For example
CHTMLWidget::m_toolTip.
Help is appreciated :)
Thank you for your help! I'm glad to have someone with excellent C++
knowledge in the team :)
Joachim