Archive for May, 2010

* C++ Derived Classes and Object Destruction

Posted on May 29th, 2010 by John. Filed under programming.


While working on lebookread I realized that the the destructor for my reader classes would never be called. lebook read has a base class (FormatReader) that exports all of the necessary functionality for use by applications using the library. All of the readers are a subclass of FormatReader. The library will find the appropriate reader for the specified ebook create a reader object and return it as a FormatReader pointer.

When you are dealing with a pointer p of type base that points to an object of type derived you need to take special care. To have the destruction of p call the derived and base destructor the base class must have a virtual destructor. Otherwise only the base class’s destructor will be called. This is one of those little things to look out for when dealing with C++.

Here is some example code to demonstrate the above.

main.cpp

#include <iostream>
 
#include "base.h"
#include "deriv.h"
 
using namespace std;
 
int main(int argc, char** argv)
{
    cout << "Base *b = new Base();" << endl;
    cout << "delete b;" << endl;
    Base *b = new Base();
    cout << " --- " << endl;
    delete b;
    cout << " --- " << endl;
    cout << "b destroyed" << endl;
 
    cout << endl;
 
    cout << "Deriv *d = new Deriv();" << endl;
    cout << "delete d" << endl;
    Deriv *d = new Deriv();
    cout << " --- " << endl;
    delete d;
    cout << " --- " << endl;
    cout << "d destroyed" << endl;
 
    cout << endl;
 
    cout << "Base *c = new Deriv();" << endl;
    cout << "delete c" << endl;
    Base *c = new Deriv();
    cout << " --- " << endl;
    delete c;
    cout << " --- " << endl;
    cout << "c destroyed" << endl;
 
    return 0;
}
#ifndef BASE_H
#define BASE_H
 
class Base
{
public:
    ~Base();
};
 
#endif /* BASE_H */

base.cpp

#include <iostream>
 
#include "base.h"
 
using namespace std;
 
Base::~Base()
{
    cout << "base dest" << endl;
}

deriv.h

#ifndef DERIV_H
#define DERIV_H
 
#include "base.h"
 
class Deriv : public Base
{
public:
    ~Deriv();
};
 
#endif /* DERIV_H */

deriv.cpp

#include <iostream>
 
#include "deriv.h"
 
using namespace std;
 
Deriv::~Deriv()
{
    cout << "deriv dest" << endl;
}

The output of this will be:

$ ./a.out 
Base *b = new Base();
delete b;
 --- 
base dest
 --- 
b destroyed
 
Deriv *d = new Deriv();
delete d
 --- 
deriv dest
base dest
 --- 
d destroyed
 
Base *c = new Deriv();
delete c
 --- 
base dest
 --- 
c destroyed

Notice that when destroying c only the Base’s destructor is called. To fix this and have both Base and Deriv’s destructors called just make Base’s destructor virtual.

#ifndef BASE_H
#define BASE_H
 
class Base
{
public:
    virtual ~Base();
};
 
#endif /* BASE_H */

This simple change will cause the output to become:

$ ./a.out 
Base *b = new Base();
delete b;
 --- 
base dest
 --- 
b destroyed
 
Deriv *d = new Deriv();
delete d
 --- 
deriv dest
base dest
 --- 
d destroyed
 
Base *c = new Deriv();
delete c
 --- 
deriv dest
base dest
 --- 
c destroyed

Now when destroying c the destructor for both Base and Deriv are called.

To compile

$ g++ base.cpp deriv.cpp main.cpp

Tags: .



* lebookread

Posted on May 16th, 2010 by John. Filed under lebookread, programming.


I have been taking a short break from blogging again. The pressure at work has only increased and is eating into a lot of my time. I haven’t been motivated to work on personal projects because well they are work. However, this has recently changed a bit.

I’ve started a Qt based library for reading ebooks in a generic manner. It is called lebookread! It is it’s early stages. So far I have it supporting epub, palmdoc pdb, ztxt pdb, tcr, and rb files. I plan to support ereader pdb, mobi, and plucker files in the near future.

The main goal of this project is to make reading ebooks easy for Qt based projects. I’ve chose to write the library in C++. This is also my first attempt at writing a library and it shows. I hope that it will be used by Sigil.

The real motivation of writing lebook read is I really want a good light weight ebook reader. The current offering have issues. I want something that is a bit more advanced in it’s rendering than FBReader. I also didn’t want anything with as large a dependency list as calibre. So, I plan on using lebookread to write my own ebook viewer.

Tags: , , , , , , , .

    Comments Off