[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