Need clarification about virtual methods & inheritance

M

mark

I have this class:
class Selections {
OSStatus Init();

protected:
CFMutableSetRef selectionObjects;
static void CFASelectionsApplier(const void* value, void* ctx);
OSType ready;
public:
Selections();
Selections(const Selections &obj);
virtual ~Selections();

virtual OSType GetSelectionScope();

virtual UInt32 GetSelectCount(SelectionFlag whichFlags);
virtual CFArrayRef GetSelObjects(SelectionFlag whichFlags);
UInt32 GetCountOfClass(SelObjectClass theClass);
CFArrayRef GetSelObjectsOfClass(SelObjectClass theClass);
virtual UInt32 GetCountOfScope(OSType theScope);
virtual CFArrayRef GetArrayofScope(OSType theScope);

virtual OSStatus MassAddSelObjects(CFArrayRef sorArray);
virtual OSStatus AddSelectededObject(SelectedObjectRef soref);
virtual OSStatus MassRemoveSelObjects(CFArrayRef sorArray);
virtual OSStatus RemoveSelectedObject(SelectedObjectRef soref);
virtual void RemoveAllSelectedObjects(SelectionFlag whichFlags);
void RemoveSelObjectsOfClass(SelObjectClass theClass);
virtual void RemoveSelObjectsOfScope(OSType theScope);
virtual void RemoveAll();
};

and a subclass:

typedef class DirView DirView;

class DVSelections: public Selections {
DirView* view;
OSType dvsReady;
public:
DVSelections(DirView* theView);
DVSelections(const DVSelections &obj);
~DVSelections();

OSType GetSelectionScope();
DirView* GetView();
};

When I attempt to compile it, the linker complains with this message:
/usr/bin/ld: Undefined symbols:
vtable for DVSelections

I was under the impression if the virtual function is not defined in a
subclass, the parent class's function will be used.
What am I missing?

This is mac OS X, XCode 2.2 with gcc 4.

TIA
Mark
 
V

Victor Bazarov

mark said:
I have this class:
class Selections {
OSStatus Init();

protected:
CFMutableSetRef selectionObjects;
static void CFASelectionsApplier(const void* value, void* ctx);
OSType ready;
public:
Selections();
Selections(const Selections &obj);
virtual ~Selections();

virtual OSType GetSelectionScope();

virtual UInt32 GetSelectCount(SelectionFlag whichFlags);
virtual CFArrayRef GetSelObjects(SelectionFlag whichFlags);
UInt32 GetCountOfClass(SelObjectClass theClass);
CFArrayRef GetSelObjectsOfClass(SelObjectClass theClass);
virtual UInt32 GetCountOfScope(OSType theScope);
virtual CFArrayRef GetArrayofScope(OSType theScope);

virtual OSStatus MassAddSelObjects(CFArrayRef sorArray);
virtual OSStatus AddSelectededObject(SelectedObjectRef soref);
virtual OSStatus MassRemoveSelObjects(CFArrayRef sorArray);
virtual OSStatus RemoveSelectedObject(SelectedObjectRef soref);
virtual void RemoveAllSelectedObjects(SelectionFlag whichFlags);
void RemoveSelObjectsOfClass(SelObjectClass theClass);
virtual void RemoveSelObjectsOfScope(OSType theScope);
virtual void RemoveAll();
};

and a subclass:

typedef class DirView DirView;

class DVSelections: public Selections {
DirView* view;
OSType dvsReady;
public:
DVSelections(DirView* theView);
DVSelections(const DVSelections &obj);
~DVSelections();

OSType GetSelectionScope();
DirView* GetView();
};

When I attempt to compile it, the linker complains with this message:
/usr/bin/ld: Undefined symbols:
vtable for DVSelections

I was under the impression if the virtual function is not defined in a
subclass, the parent class's function will be used.
What am I missing?

Could it be you're not linking all object modules together when you need to?
Also, remember that all virtual functions that are not declared pure need
to be defined. Did you define any of them or did you just declare them?

If none of that helps, we probably can't really help you, since (a) you
didn't post the whole code, and (b) your issue is compiler-specific,
apparently, so you might want to consider posting to 'gnu.g++.help'.

V
 
D

David Harmon

On Fri, 13 Jan 2006 14:34:38 +1300 in comp.lang.c++, mark
I was under the impression if the virtual function is not defined in a
subclass, the parent class's function will be used.

Yes, however if you declare it in the subclass declaration, that
means you are promising to define it somewhere.
 
M

mark

Could it be you're not linking all object modules together when you need to?
Also, remember that all virtual functions that are not declared pure need
to be defined. Did you define any of them or did you just declare them?

If none of that helps, we probably can't really help you, since (a) you
didn't post the whole code, and (b) your issue is compiler-specific,
apparently, so you might want to consider posting to 'gnu.g++.help'.

V

All virtual functions for the base class have been declared and coded.

There is a function with this code:

OSStatus CreateNewDVSelection(DirView* theView) {
if (theView==nil) {return paramErr;}
DVSelectionsRef dvs=nil;

try {
(1) dvs=new DVSelections(theView);
}
catch (OSStatus OE) {
if (dvs) {delete dvs;}
return OE;
}
catch (...) {
if (dvs) {delete dvs;}
return memFullErr;
};

return 0;
};

Could (1) be causing the problem?
 
V

Victor Bazarov

mark said:
mark said:
I have this class:
[..]
I was under the impression if the virtual function is not defined

Virtual functions have to be either declared *pure* or defined (or both).
You cannot have a virtual function not defined, and not pure.

That's what you're missing. You need to define all functions that are
not pure.
All virtual functions for the base class have been declared and coded.

What do you mean by "coded"? Defined? Are you linking the module where
they are defined into your program?
There is a function with this code:

OSStatus CreateNewDVSelection(DirView* theView) {
if (theView==nil) {return paramErr;}

What is 'nil'?
DVSelectionsRef dvs=nil;

What is 'nil'? What is 'DVSelectionsRef'?
try {
(1) dvs=new DVSelections(theView);
}
catch (OSStatus OE) {
if (dvs) {delete dvs;}
return OE;
}
catch (...) {
if (dvs) {delete dvs;}
return memFullErr;
};

return 0;
};

Could (1) be causing the problem?

No. The code itself if fine. The fact that you didn't define all
the virtual functions, or didn't provide the definitions to the linker,
is the problem.

V
 
M

mark

"Victor Bazarov said:
mark said:
mark wrote:
I have this class:
[..]
I was under the impression if the virtual function is not defined

Virtual functions have to be either declared *pure* or defined (or both).
You cannot have a virtual function not defined, and not pure.

That's what you're missing. You need to define all functions that are
not pure.
Thanks. Now I get it.
What is 'nil'?
Old pascal name for NULL.
 
M

mark

David Harmon said:
On Fri, 13 Jan 2006 14:34:38 +1300 in comp.lang.c++, mark


Yes, however if you declare it in the subclass declaration, that
means you are promising to define it somewhere.

I didn't define the virtual in the subclass, only the base class (and
it's not pure).
 
G

Greg

mark said:
I didn't define the virtual in the subclass, only the base class (and
it's not pure).

If a function is declared virtual in a base class, it is also virtual
in every derived class whether or not the derived class uses the
"virtual" keyword in its declaration of the function.

I suspect that you have not defined the (virtual) destructor for
DVSelections anywhere.

Greg
 
M

mark

"Greg said:
If a function is declared virtual in a base class, it is also virtual
in every derived class whether or not the derived class uses the
"virtual" keyword in its declaration of the function.

I suspect that you have not defined the (virtual) destructor for
DVSelections anywhere.
DOH! DOH! DOH! DOH!
Looked over the code a dozen times and missed this little detailed
completely.
Thanks.
 
C

CodeSafe

Bahhh
if you want to create a pure virtual interface with pure virtual
destructor do
..h file:

class IMyPureVirtualClass
{
public:
virtual ~IMyPureVirtualClass() = 0;

virtual void SomeInterfaceFunction() = 0;
//...
};

..cpp file:
IMyPureVirtualClass::~IMyPureVirtualClass()
{
//empty destructor (declared as pure virtual)
}

now, when implementing the interface you should keep interface
functions virtual.
destructors in class declerations should ALWAYS be virtual or else they
might not get called, and it might cause mem leaks.

cheers
 
B

Ben Pope

CodeSafe said:
Bahhh
if you want to create a pure virtual interface with pure virtual
destructor do
.h file:

class IMyPureVirtualClass
{
public:
virtual ~IMyPureVirtualClass() = 0;

virtual void SomeInterfaceFunction() = 0;
//...
};

.cpp file:
IMyPureVirtualClass::~IMyPureVirtualClass()
{
//empty destructor (declared as pure virtual)
}

I tend to prefer a header only implementation:

public:
virtual ~IMyPureVirtualClass() = 0 {};




Ben Pope
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top