Click to See Complete Forum and Search --> : help with multiple inheritance / abstract class


Juergen Wolther
December 4th, 2001, 09:38 AM
hi,
I tried to implement the following (stripped down to the essencials):


// first a usual class like you see it everywhere as base-class

class SomeBaseClassA
{
private:
int iSomeMemberA1;
int iSomeMemberA2;

public:
void SomeFunctionA1(){};
void SomeFunctionA2(){};
};

// now a abstract base-class (I think this is the problem)

class SomeBaseClassB
{
public:
virtual void SomeFunctionB(SomeOtherClass *pInstance) = 0;
};

// ok and now a derived class, derived from the classes shown above

class DerivedClass : public SomeBaseClassA, SomeBaseClassB
{
// Overriding the abstract function of SomeClassB
void SomeFunctionB(SomeOtherClass *pInstance){};
};


// Ok, and now a sample-code to use the construct shown above
// just to show you the problem

DerivedClass *pInstance = new DerivedClass();

// doing some not dangerous things with the class-instance
// but SURPRISE: in the next line of code the program crashes with a page-fault

delete pInstance;




that's it ! destroying the instance causes a page-fault. I am not doing any weird things in any destructor. in fact I have NO destructors defined at all by now.

if I only derive DerivedClass from SomeClassA, which is not abstract, everything works fine and no page-fault occurs.

Ah yeah, right before the page-fault I get the following error-dialog from the runtime:

=======================================================
Debug Assertion Failed

Program: Name of my Program
File: dbgheap.c
Line: 1017

Expression: BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

...and some advises to try to debug the program.
=======================================================
do you know why this is so ? did I something wrong in deriving or declaring. I have no clue about it.

thanx in advance

Juergen

Juergen Wolther
December 4th, 2001, 11:39 AM
Hi again,
I did a lot of tests by now, and found out that:

a.) if I comment the declaration of the pure virtual function in the abstract class out everything works fine again. So it looks like only a entirely empty class definition works.
b.) if I use any kind of pure virtual function (no matter which signature) the page fault occurs again.

has anybody a clue about what's wrong ?

Juergen

Paul McKenzie
December 4th, 2001, 12:08 PM
The following program shows no problems:

// first a usual class like you see it everywhere as base-class
class SomeBaseClassA
{
private:
int iSomeMemberA1;
int iSomeMemberA2;

public:
void SomeFunctionA1(){};
void SomeFunctionA2(){};
};// now a abstract base-class (I think this is the problem)

class SomeBaseClassB
{
public:
virtual void SomeFunctionB(int n) = 0;
};// ok and now a derived class, derived from the classes shown above

class DerivedClass : public SomeBaseClassA, SomeBaseClassB
{
// Overriding the abstract function of SomeClassB
void SomeFunctionB(int n){};
};

// Ok, and now a sample-code to use the construct shown above// just to show you the problem
int main()
{
DerivedClass *pInstance = new DerivedClass();
delete pInstance;
}



Since I don't know what SomeOtherClass is, I just replaced it with a simple "int". There were no problems running this program.

Regards,

Paul McKenzie

Juergen Wolther
December 4th, 2001, 12:19 PM
Hi Paul,
thanx for making me believe much more that it is no problem of my code.
SomeOtherClass is a wrapper-class for a windows-menuitem. but there is no problem.
I tested a lot in the last 2 hours, and I found another interesting thing about my problem:

The assertion I mentioned above in VC++ is a result of the fact that when a debug-version is compiled some debug-code is compiled into it.
when I compiled my whole project (now really big uuhh) in release-mode as release-version the assertion-message never popped up again.

hmm... like The Smith would sing: "Strangeways here we come..." ;o)

any idea about this ?

greetinx

Juergen

Paul McKenzie
December 4th, 2001, 01:15 PM
When you compile in release mode, the MFC assert messages are not compiled into your code. I believe the ASSERT macro is defined as nothing when you compile a release version, so any assertions are just not displayed to you.

Was the error that you got an MFC generated error box or an OS generated error box? You can tell the difference in that the OS generated error box will appear with a "Details" button that just gets you the state of the registers, while the MFC message box gives you information on the line number, source file, plus other extras.

MFC catches errors that the OS cannot detect. For example, the OS cannot detect if you are writing to your programs memory heap illegally -- it can only detect when you are writing (or reading) outside of your entire program's memory address. The heap is considered to be part of your program, so for example, if you call malloc( ) and then you call free( ), but then you write to the freed memory again, the OS can't detect this since the freed pointer would still be pointing to a valid portion of your program's memory. However, it is not a valid pointer in terms of keeping the heap valid, and only the program (MFC in this case) can detect this.

Therefore there may still be something wrong with the program if you can't get a good debug version to compile and run. It might be not the code you posted, but some other dynamic memory allocations somewhere else are messing up the heap enough to affect other parts of your code.

Regards,

Paul McKenzie