Help with Virtual methods

D

Dennis

Hi,
This may be a simple answer for somebody, but I'm unable to figure
it out. In a nutshell:

I have a base class defined. Let's call it XClient. Inside XClient I
have a virtual method called messageHandler, so it looks something
like this:

class XClient {
......
public:
virtual bool messageHandler(.....) = 0;
};

I then have a derived class looking something like:

class XClientWrapper:public XClient{
public:
bool messageHandler(....) = 0;
};

I am using this XClientWrapper class in two places in my code. In one
section I have another class that inheirits XClientWrapper's
attributes. Seems to compile and link fine.

In another section of code I specify an instance of XClientWrapper,
just a simple:

XClientWrapper *ptr = new XClientWrapper;

WHen I compile I get an error stating:
Cannot allocate an object of type XClientWrapper since the
following virtual functions are abstract. (messageHandler).

If I remove the ' = 0;' from the redefinition of messageHandler in
XClientWrapper it will compile and link. However, once I do this and
try to compile my other code that worked fine with the '=0', I get the
following link error:

Undefined reference to XClientWrapper virtual table.

It works one way with the '= 0' and not the other, and vice versa.
Any ideas?


Thanks in advance!

Dennis
 
R

Ron Natalie

Dennis said:
If I remove the ' = 0;' from the redefinition of messageHandler in
XClientWrapper it will compile and link. However, once I do this and
try to compile my other code that worked fine with the '=0', I get the
following link error:

Undefined reference to XClientWrapper virtual table.

It works one way with the '= 0' and not the other, and vice versa.
Any ideas?

What exactly are you trying to do? You can not instantiate a function
with pure virtual functions (= 0 specifier). The pure specifier leaves the
class abstract. If XClientWrapper is concrete (i.e., no unoverridden
pure virtual functions), then you must provide the implementation of the
methods you use.
 
D

Dennis

Actually, you can even disregard the '=0' from the XClientWrapper.
That was just the latest iteration I tried to get it to compile and
link from both sections of code.

What I had originally started with was not even overridding the
messageHandler in XClientWrapper and just inheirting it from XClient.
Again, I would get the same compile and link errors. One section of
code would compile and link fine without messageHandler defined in
XClientWrapper, but another section would complain during compilation
that it couldn't allocate the object since the function messageHandler
was abstract. If I stuck the definition into XClientWrapper it would
then compile fine, but the other section of code that use to work
before would now complain.

Ideas?

Dennis
 
J

John Harrison

Dennis said:
Actually, you can even disregard the '=0' from the XClientWrapper.
That was just the latest iteration I tried to get it to compile and
link from both sections of code.

What I had originally started with was not even overridding the
messageHandler in XClientWrapper and just inheirting it from XClient.
Again, I would get the same compile and link errors. One section of
code would compile and link fine without messageHandler defined in
XClientWrapper, but another section would complain during compilation
that it couldn't allocate the object since the function messageHandler
was abstract. If I stuck the definition into XClientWrapper it would
then compile fine, but the other section of code that use to work
before would now complain.

Ideas?

As far as I can tell, what you are failing to do is give a definition for
XClientWrapper::messageHandler. That's what the link error is telling you.
Isn't it obvious? How do you expect your program to work when you don't
provide a definition for a function?

john
 
D

Dennis

The definition is provided at the XClient level and then inheirited to
XClientWrapper. XClientWrapper can then decide to override it if it
wants to, which I've decided not to do. What I can't figure out is
why the linker error is showing up in one instance of the class and
not another.

Dennis
 
J

John Harrison

Dennis said:
The definition is provided at the XClient level and then inheirited to
XClientWrapper. XClientWrapper can then decide to override it if it
wants to, which I've decided not to do. What I can't figure out is
why the linker error is showing up in one instance of the class and
not another.

Dennis

class XClient {
......
public:
virtual bool messageHandler(.....) = 0;
};

That's looks like a pure virtual function, not a function definition.

I'm telling you that you haven't defined the function, Ron is telling you
that you haven't defined the function, the linker is telling you that you
haven't defined the function. Now maybe there is something you aren't
telling us, but my money is one the possibility that you misunderstand
something, and you haven't defined the function.

john
 
D

Dennis

John,
I apologize for my naiveness (is that a word?). This is my first
experience with virtual functions. Yes, the pure virtual function was
first defined in XClient. I then inheirited XClient into
XClientWrapper, which I then want to make use of the messageHandler
virtual method. You were asking for my definition. I didn't think
that I needed to define it again explicitly in XClientWrapper but
could just use it like:

bool
XClientWrapper::messageHandler(....) // argument list the same as
XClient
{
....code...
}

without having to define it explicitly in XClientWrapper class
(figured it inheirited the definition). I've taken this approach with
several applications and it has compiled, linked, and run fine.

However, with this one application that I've run into it's complaining
about the definition now. Just can't figure out why it worked for one
and not the other. Is it a compiler fluke that it worked before?

Thanks for your patience.

Dennis
 
J

jeffc

Dennis said:
Actually, you can even disregard the '=0' from the XClientWrapper.
That was just the latest iteration I tried to get it to compile and
link from both sections of code.

What I had originally started with was not even overridding the
messageHandler in XClientWrapper and just inheirting it from XClient.

But that is exactly the same thing. If you don't specify it, it's still
pure virtual. In a manner of speaking, it's still "=0" until you specify
otherwise, for all subclasses.
 
J

jeffc

Dennis said:
The definition is provided at the XClient level and then inheirited to
XClientWrapper. XClientWrapper can then decide to override it if it
wants to, which I've decided not to do.

You don't have the option of making that decision. There is nothing wrong
with providing a definition of the pure virtual function in the abstract
base class (contrary to what many people seem to think.) However, you can
NOT aviod explicity defining a function in the base class. In this case,
you would simply call the base class. i.e.

class XClient {
......
public:
virtual bool messageHandler(.....) = 0;
};

class XClientWrapper:public XClient{
public:
bool messageHandler(....) = 0;
};

bool XClientWrapper::messageHandler(...)
{
return XClient::messageHandler(...); // assuming this is actually
defined somewhere
}
 

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

Similar Threads


Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top