Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old May 25th, 2006, 2:59 PM   #1
Laterix
Newbie
 
Join Date: May 2006
Posts: 3
Rep Power: 0 Laterix is on a distinguished road
About pure virtual function calls

Hi all, I'm new here.

My question is about dynamic binding and polymorphism of the C++. I'm working on my first C++ project. Before I used Java.

So, I have abstract base class that implements some of the functions, but not all. So there are also pure virtual functions in my abstract base class. Now I have function foo() which is implemented in abstract class and function goo() which is pure virtual function.

I get linker error with code like this:
Base::foo()
{
    this->goo();
}
So I'm trying to call undefined function goo, which is defnied in subclasses. Is this just not possible in C++ or am I doing something wrong here? I believe that this is possible in Java.
Laterix is offline   Reply With Quote
Old May 25th, 2006, 3:17 PM   #2
aznluvsmc
Hobbyist Programmer
 
Join Date: Aug 2005
Posts: 137
Rep Power: 4 aznluvsmc is on a distinguished road
It would be easier if you posted your entire code for use to see.
aznluvsmc is offline   Reply With Quote
Old May 26th, 2006, 5:16 AM   #3
Laterix
Newbie
 
Join Date: May 2006
Posts: 3
Rep Power: 0 Laterix is on a distinguished road
Quote:
Originally Posted by aznluvsmc
It would be easier if you posted your entire code for use to see.
Thanks for you reply. It's a lot of code and hard to cut just needed parts so that it would still make sense.

But I draw an example UML of the situation, which should be enough to illustrate my problem.

So, I have this kind of inheritance relationship. MyAdapter implements Operation1() as shown in UML. Operation2() is pure virtual function in MyAdapter and it is implmented in subclass SpesificAdapter. Now the problem is that I get error with the line this->operation2(); in MyAdaptor.
Laterix is offline   Reply With Quote
Old May 26th, 2006, 6:07 AM   #4
grumpy
Programming Guru
 
grumpy's Avatar
 
Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,221
Rep Power: 5 grumpy is on a distinguished road
Yes, it is possible to implement your design in C++.

It is not necessary to post your complete program. It would help if you took your class and cut it down to a small but complete example that (most importantly) exhibits your problem. The process of creating that example may make it clear to you what the problem is (i.e. you might succeed in solving it without help). If not, by providing complete information, we have more chance of helping. It also helps if you tell us what error message you're getting from your compiler (or linker).

From the information you've given, you shouldn't need to use the "this->" prefix when calling goo() within foo(). The most likely causes of your error that I can think of (noting that you haven't provided enough information) are;

1) foo() is static (in which case there is no "this" pointer when called)

2) you have mixed up return types or argument types of the functions in some way that introduces an incompatibility.
grumpy is offline   Reply With Quote
Old May 26th, 2006, 6:49 AM   #5
Tegelane
Newbie
 
Join Date: May 2006
Location: Estonia
Posts: 8
Rep Power: 0 Tegelane is on a distinguished road
#include <iostream>

using namespace std;

class Base
{
public:
  Base() {};
  ~Base() {};
  virtual void stuff1();
  virtual void stuff2();
};

void Base::stuff1()
{
 stuff2();
}

class Derived : public Base
{
public:
  Derived() {};
  ~Derived() {};
  void stuff2();
};

void Derived::stuff2()
{
  cout<<"asdasd"<<endl;
  return;
}

int main()
{
Derived d;
d.stuff1();
return 0;
}

the code should be something like this. i think..
and compiling this gives me a linker error about undefined Base::stuff2()

/tmp/ccBAAYa4.o.rodata._ZTV4Base[vtable for Base]+0x18): undefined reference to `Base::stuff2()'

if i implement Base::stuff2() witch does nothing, it works as needed
Tegelane is offline   Reply With Quote
Old May 26th, 2006, 7:04 AM   #6
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
virtual void stuff2() = 0;
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code.
Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers
DaWei is offline   Reply With Quote
Old May 26th, 2006, 7:33 AM   #7
grumpy
Programming Guru
 
grumpy's Avatar
 
Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,221
Rep Power: 5 grumpy is on a distinguished road
Dawei's nailed it. The reason is that you declared the function as virtual but you did not (despite what you said in the original post) declare it as pure virtual (the "=0" on the end of a declaration of a virtual function achieves that).

For reference, the error message you received is from the linker. The function as your declared it is not pure virtual, so an implementation of it is needed.
grumpy is offline   Reply With Quote
Old May 26th, 2006, 2:25 PM   #8
Laterix
Newbie
 
Join Date: May 2006
Posts: 3
Rep Power: 0 Laterix is on a distinguished road
Thank you for your effeort everyone! I'm ashamed to say that my example was little missleading.

I actually call pure virtual function from abstract class constructor. And I think that is really a problem, because when I create a new object of SpesificAdapter it automatically calls parent class constructor before it own and there it trys to call operation2() which doesn't exists yet. Am I right?

Anyway, I found a workaround to this problem. You have been very nice. Hopefully I can help someone with Java or PHP in the future.
Laterix is offline   Reply With Quote
Old May 26th, 2006, 2:33 PM   #9
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
You might want to think about a couple of mundane things. What does the compiler require? Once that's satisfied, what does the linker require? Once that's satisfied, what does execution require? You'll have a hard time burping the baby if 'is mama hasn't been born yet. Which came first? The chicken or the egg or the road or the joke?
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code.
Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers
DaWei is offline   Reply With Quote
Old May 26th, 2006, 4:59 PM   #10
grumpy
Programming Guru
 
grumpy's Avatar
 
Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,221
Rep Power: 5 grumpy is on a distinguished road
Quote:
Originally Posted by Laterix
I actually call pure virtual function from abstract class constructor. And I think that is really a problem, because when I create a new object of SpesificAdapter it automatically calls parent class constructor before it own and there it trys to call operation2() which doesn't exists yet. Am I rigt?
Yes, you're right. It is generally bad practice to call any virtual function from a constructor (whether pure or not). The reason is that the constructor can only call a virtual function statically (i.e. the constructor for Base can only call Base::virtual_function(), which is not normally the intent of calling a virtual function). The reason for this is construction order: a Base class constructor is invoked before the derived class constructor and various properties of the class do not come together until the derived class is constructed. This means that, when the Base constructor is called, there is no information available to say the object is really a Derived, which mean that Derived::virtual_function() cannot be invoked.

Pure virtual functions are worse: being pure virtual, they might not be defined by the base class, which means there is no Base::virtual_function() to call. That normally shows up as a linker error.
Quote:
Originally Posted by Laterix
Anyway, I found a workaround to this problem. You have been very nice. Hopefully I can help someone with Java or PHP in the future.
The workaround is to create the object, before calling the virtual function. For example (using your case);
Base *object = new Derived;
object->virtual_function();
object->nonvirtual_which_calls_virtual_function();
grumpy is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 1:38 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC