By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,669 Members | 1,634 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,669 IT Pros & Developers. It's quick & easy.

Why can't I do this?

P: n/a
Dear Gurus,

This is a fairly simple question, but I can't figure out what the answer is.
I can easily change my code, but I want to know why I can't do this to
further my knowledge of the C++ language (and OO):

class a
{
public:
a(){ vm(); }
virtual void vm() = 0;
};

class b : public a
{
public:
void vm() { }
};

int main()
{
b B;

return 0;
}

VC++ says: "error LNK2001: unresolved external symbol "public: virtual void
__thiscall a::vm(void)"

I understand that 'a' doesn't have a implementation of 'vm', but also I
cannot create an instance of 'a' either (because it has a pure virtual
function) so when I create a 'b' why can't 'a's constructor call 'b's 'vm'?

Quentin.
Jul 19 '05 #1
Share this Question
Share on Google+
14 Replies


P: n/a
On Wed, 17 Sep 2003 22:46:09 GMT, "Quentin" <IH*******@SpamSux.com> wrote:
This is a fairly simple question, but I can't figure out what the answer is.
I can easily change my code, but I want to know why I can't do this to
further my knowledge of the C++ language (and OO):

class a
{
public:
a(){ vm(); }
virtual void vm() = 0;
};

class b : public a
{
public:
void vm() { }
};

int main()
{
b B;

return 0;
}

VC++ says: "error LNK2001: unresolved external symbol "public: virtual void
__thiscall a::vm(void)"

I understand that 'a' doesn't have a implementation of 'vm', but also I
cannot create an instance of 'a' either (because it has a pure virtual
function) so when I create a 'b' why can't 'a's constructor call 'b's 'vm'?


This is a FAQ.

Look it up in the FAQ.

If necessary, first look up where the FAQ is (Google, this group).
Hth.,

- Alf

Jul 19 '05 #2

P: n/a
> Look it up in the FAQ.

Thanks Alf!

Quentin.
Jul 19 '05 #3

P: n/a
"Quentin" <IH*******@SpamSux.com> wrote in message
news:Ru*********************@news1.calgary.shaw.ca ...
Dear Gurus,

This is a fairly simple question, but I can't figure out what the answer is. I can easily change my code, but I want to know why I can't do this to
further my knowledge of the C++ language (and OO):

class a
{
public:
a(){ vm(); }
virtual void vm() = 0;
};

class b : public a
{
public:
void vm() { }
};

int main()
{
b B;

return 0;
}

VC++ says: "error LNK2001: unresolved external symbol "public: virtual void __thiscall a::vm(void)"

I understand that 'a' doesn't have a implementation of 'vm', but also I
cannot create an instance of 'a' either (because it has a pure virtual
function) so when I create a 'b' why can't 'a's constructor call 'b's 'vm'?
Quentin.


Because at the time of construction of A part "this" pointer is still of
type A, hence it does not know anything about B yet. In other words,
construction starts at the top of inheritance tree, and the type of this
pointer follows. BTW, Mayers in his book Effectife C++ has a chapter about
this... you shouldn't (in most cases) call virtual functions from
constructors.

Martin
Jul 19 '05 #4

P: n/a
"Quentin" <IH*******@SpamSux.com> wrote in message
news:Ru*********************@news1.calgary.shaw.ca ...
Dear Gurus,

This is a fairly simple question, but I can't figure out what the answer is. I can easily change my code, but I want to know why I can't do this to
further my knowledge of the C++ language (and OO):

class a
{
public:
a(){ vm(); }
virtual void vm() = 0;
};

class b : public a
{
public:
void vm() { }
};

int main()
{
b B;

return 0;
}

VC++ says: "error LNK2001: unresolved external symbol "public: virtual void __thiscall a::vm(void)"

I understand that 'a' doesn't have a implementation of 'vm', but also I
cannot create an instance of 'a' either (because it has a pure virtual
function) so when I create a 'b' why can't 'a's constructor call 'b's 'vm'?
Quentin.

I'm by no means a guru, and of course you can check the FAQ, but I believe
this is the problem:
Class A is an abstract base class containing an unimplemented virtual
function. Therefore, you cannot call vm() from the Class A constructor,
because in Class A it doesn't exist.

Call vm() from Class B's constructor.

Think about it... why should the compiler allow you to call Class A's vm()
if it has no function body? The compiler is doing you a favor here.

An additional question: were you to derive additional classes from A, how
would the compiler know which instance of vm() to call in A's constructor?

Jul 19 '05 #5

P: n/a

"Quentin" <IH*******@SpamSux.com> wrote in message
news:Ru*********************@news1.calgary.shaw.ca ...
Dear Gurus,

This is a fairly simple question, but I can't figure out what the answer is. I can easily change my code, but I want to know why I can't do this to
further my knowledge of the C++ language (and OO):

class a
{
public:
a(){ vm(); }
virtual void vm() = 0;
};

class b : public a
{
public:
void vm() { }
};

int main()
{
b B;

return 0;
}

VC++ says: "error LNK2001: unresolved external symbol "public: virtual void __thiscall a::vm(void)"

I understand that 'a' doesn't have a implementation of 'vm', but also I
cannot create an instance of 'a' either (because it has a pure virtual
function) so when I create a 'b' why can't 'a's constructor call 'b's

'vm'?

Whoa dude, you had it there for a minute. Now step back and think about
what you're saying. Why would a base class EVER need to know anything about
any of its subclasses? Inheritance doesn't work that way. When you create
a b, b's constructor gets called, which means a's constructor is going to
get called. But a base class function shouldn't call a subclass function.
Once you're in code for a, all it sees is a.

By the way, just because a is abstract doesn't mean you can't give a
definition for the pure virtual function. It's a common mistake to think
that though. It's often a useful technique to make a function pure virtual,
but then provide a definition that the base classes can call from their
overridden function, to do at least some common work. It might even be all
that some subclasses need to do.
Jul 19 '05 #6

P: n/a

"jeffc" <no****@nowhere.com> wrote in message
news:3f********@news1.prserv.net...
Whoa dude, you had it there for a minute. Now step back and think about
what you're saying. Why would a base class EVER need to know anything about any of its subclasses? Inheritance doesn't work that way. When you create a b, b's constructor gets called, which means a's constructor is going to
get called. But a base class function shouldn't call a subclass function.


I was talking only about the constructor in this case, of course, not the
general case of function overriding. Constructor time is different.
Jul 19 '05 #7

P: n/a
> Whoa dude, you had it there for a minute. Now step back and think about
what you're saying. Why would a base class EVER need to know anything about any of its subclasses? Inheritance doesn't work that way. When you create a b, b's constructor gets called, which means a's constructor is going to
get called. But a base class function shouldn't call a subclass function.
Once you're in code for a, all it sees is a.
I get it now. Whoa dude :) hahaha!
By the way, just because a is abstract doesn't mean you can't give a
definition for the pure virtual function. It's a common mistake to think
that though. It's often a useful technique to make a function pure virtual, but then provide a definition that the base classes can call from their
overridden function, to do at least some common work. It might even be all that some subclasses need to do.


Whoa dude, I did not know that! That could be very useful. Thanks for the
tip!

Quentin.
Jul 19 '05 #8

P: n/a
"Bill Thompson" <bi*****@ixnayontheamspayrgv.rr.com> wrote in message news:<dm*******************@twister.austin.rr.com> ...
"Quentin" <IH*******@SpamSux.com> wrote in message
I'm by no means a guru, and of course you can check the FAQ, but I believe
this is the problem:
Class A is an abstract base class containing an unimplemented virtual
function. Therefore, you cannot call vm() from the Class A constructor,
because in Class A it doesn't exist.

Call vm() from Class B's constructor.

Think about it... why should the compiler allow you to call Class A's vm()
if it has no function body? The compiler is doing you a favor here.

An additional question: were you to derive additional classes from A, how
would the compiler know which instance of vm() to call in A's constructor?


Note that this is only true for calls in constructors. It's perfectly
valid to call an abstract function from any function except from
constructors and destructors (?).

BTW it is the central idea in the Template Method Pattern.

Regards,

Marcelo Pinto
Jul 19 '05 #9

P: n/a
"Marcelo Pinto" <mp****@tecnolink.com.br> wrote in message
news:e3**************************@posting.google.c om...
"Bill Thompson" <bi*****@ixnayontheamspayrgv.rr.com> wrote in message news:<dm*******************@twister.austin.rr.com> ...
"Quentin" <IH*******@SpamSux.com> wrote in message
I'm by no means a guru, and of course you can check the FAQ, but I believe this is the problem:
Class A is an abstract base class containing an unimplemented virtual
function. Therefore, you cannot call vm() from the Class A constructor,
because in Class A it doesn't exist.

Call vm() from Class B's constructor.

Think about it... why should the compiler allow you to call Class A's vm() if it has no function body? The compiler is doing you a favor here.

An additional question: were you to derive additional classes from A, how would the compiler know which instance of vm() to call in A's

constructor?
Note that this is only true for calls in constructors. It's perfectly
valid to call an abstract function from any function except from
constructors and destructors (?).

BTW it is the central idea in the Template Method Pattern.

Regards,

Marcelo Pinto


Yes, of course, after construction the vtable has been initialized. I
should have made it more obvious I was referring to constructors, not
calling virtual functions in general.
Jul 19 '05 #10

P: n/a

"Quentin" <IH*******@SpamSux.com> wrote in message
news:41*********************@news1.calgary.shaw.ca ...
By the way, just because a is abstract doesn't mean you can't give a
definition for the pure virtual function. It's a common mistake to think that though. It's often a useful technique to make a function pure virtual,
but then provide a definition that the base classes can call from their
overridden function, to do at least some common work. It might even be

all
that some subclasses need to do.


Whoa dude, I did not know that! That could be very useful. Thanks for

the tip!


I had a typo - I meant "provide a definition that the *subclasses* can call
from their overridden function".

Example. Program for a football game. You have football players.

class FootballPlayer
class Punter : public FootballPlayer
class DefensiveEnd : public FootballPlayer

You don't have any players on the field that are so generic that you'd
create a FootballPlayer - everyone plays a specific position. Therefore,
you make FootballPlayer abstract. But in case of crazy plays, you want
every player on the field to be able to make a tackle. You might have a
pure virtual function called Tackle() which provides some basic tackling
technique.

class FootballPlayer
{
public:
void Tackle() = 0;
};

You might override Tackle() if there is some special technique defensive
players might use. But there's nothing wrong with defining
void FootballPlayer::Tackle()
{
// tackle in some basic way
}

Then Punter could just do
void Punter::Tackle()
{
FootballPlayer::Tackle(); // the basic base function is good enough
}

The DefensiveEnd might add
void DefensiveEnd::Tackle()
{
FootballPlayer::Tackle();
// plus add a harder hit, or trying to punch the ball away on the way down
}
Jul 19 '05 #11

P: n/a
jeffc <no****@nowhere.com> spoke thus:
You don't have any players on the field that are so generic that you'd
create a FootballPlayer - everyone plays a specific position. Therefore,
you make FootballPlayer abstract. But in case of crazy plays, you want
every player on the field to be able to make a tackle. You might have a
pure virtual function called Tackle() which provides some basic tackling
technique. class FootballPlayer
{
public:
void Tackle() = 0;
}; You might override Tackle() if there is some special technique defensive
players might use. But there's nothing wrong with defining
void FootballPlayer::Tackle()
{
// tackle in some basic way
} Then Punter could just do
void Punter::Tackle()
{
FootballPlayer::Tackle(); // the basic base function is good enough
}


Like football eh? ;) Seriously, I'm still a C++ newb, so I'm not seeing the
point of defining a pure virtual function and then overriding it. Why not
just make it a regular virtual function?

--
Christopher Benson-Manica | Jumonji giri, for honour.
ataru(at)cyberspace.org |

(blank space follows, sorry)











Jul 19 '05 #12

P: n/a

"Christopher Benson-Manica" <at***@nospam.cyberspace.org> wrote in message news:bk**********@chessie.cirr.com...

Like football eh? ;) Seriously, I'm still a C++ newb, so I'm not seeing the
point of defining a pure virtual function and then overriding it. Why not
just make it a regular virtual function?

Why use function overloading, just give everything seperate names?
Because it makes sense to have the base class behavior impelemented
in a function of the same name, even if you're forced to think about
whether that is the proper behavior (by itself) in a derived class.
Jul 19 '05 #13

P: n/a
Ron Natalie <ro*@sensor.com> spoke thus:
Why use function overloading, just give everything seperate names?
Because it makes sense to have the base class behavior impelemented
in a function of the same name, even if you're forced to think about
whether that is the proper behavior (by itself) in a derived class.


M... (denseness/cluelessness alert!)

I thought the point of a pure virtual function was to force subclasses to
implement it, since the base class explicitly declines to do so. If the base
class wants to provide an implementation of a member function, what is
accomplished by declaring it to be purely virtual? Is it so a class that uses
classes derived from the base can choose to override the base virtual
function......?

--
Christopher Benson-Manica | Jumonji giri, for honour.
ataru(at)cyberspace.org |
Jul 19 '05 #14

P: n/a

"Christopher Benson-Manica" <at***@nospam.cyberspace.org> wrote in message news:bk**********@chessie.cirr.com...
Ron Natalie <ro*@sensor.com> spoke thus:
Why use function overloading, just give everything seperate names?
Because it makes sense to have the base class behavior impelemented
in a function of the same name, even if you're forced to think about
whether that is the proper behavior (by itself) in a derived class.
M... (denseness/cluelessness alert!)

I thought the point of a pure virtual function was to force subclasses to
implement it, since the base class explicitly declines to do so.


The first part of your statement is true, the second isn't. It forces the
derived classes (at least those who are going to be concrete) to provide
an implementation, but it doesn't say boo about whether the base class
does or not.
If the base
class wants to provide an implementation of a member function, what is
accomplished by declaring it to be purely virtual?
We just told you, and the football example was provided. I'll give you a more real
world one right out of our main product. Inside we have a bunch of objects that
get passed around generically. They have various functions they implement
(including such common things as the relational operators, serialize output, etc...).
Lets take the serialize function. There is a default behavior of just writing an
encoded version of the object type (which there is obtainable from the base class
via another virtual function). However, that's NOT good enough for many of
the objects. Therefore, I make the base class method pure, so that it MUST
be overridden. This forces the derived class writer to make the decision between
using the default behavior or writing a different implementation. What it doesn't
allow (and we were screwed by this a couple of times before we did this) is
to forget to put an explicit statement of the proper behavior in his class definition.

Is it so a class that uses
classes derived from the base can choose to override the base virtual
function......?


Well a class can always chose to override the function. What it does is force
the derived class to make an explicit statement as to whether he wants the
base behavior or something else.
Jul 19 '05 #15

This discussion thread is closed

Replies have been disabled for this discussion.