virtual void method() = 0; problem

Please support our C++ advertiser: Intel Parallel Studio Home
Reply

Join Date: Mar 2009
Posts: 3
Reputation: eduardocoelho is an unknown quantity at this point 
Solved Threads: 0
eduardocoelho eduardocoelho is offline Offline
Newbie Poster

virtual void method() = 0; problem

 
0
  #1
Mar 29th, 2009
Hi folks, I tried to read some past threads in this forum but I didn't find one that solves the problem I'm dealing about.
I have experience with Java/OO programming and I'm developing a project using C++ (I have some background with C/C++ programming but I'm messing around some issues of the C++ language).
Well let's go to the problem:

My application uses the Model/View/Controller pattern and since I'm trying to add a ProgressBar to my "View" module I'm using the Observer Pattern, so I created two classes (I'd refer it as "interfaces")

  1. class AbstractObserver {
  2. public:
  3. virtual void update(int progressStatus) = 0;
  4.  
  5. };

  1. class AbstractSubject {
  2. public:
  3. virtual void registerObserver(AbstractObserver* observer) = 0;
  4. virtual void removeObserver(AbstractObserver* observer) = 0;
  5. virtual void notifyObserver() = 0;
  6. };

Since my "View"class (named IMDialog) is the Observer, it extends the "AbstractObserver" class, and so implements the "update(int progressStatus)" method. Ex:

  1. #include "AbstractObserver.h"
  2. #include "IupDialogWrapper.h"
  3.  
  4. class IMDialog : public AbstractObserver, public IupDialogWrapper {
  5. public:
  6. void update(int progressStatus) {
  7. cout << "IMDialog: " << progressStatus << endl;
  8. }
  9.  
  10. // another methods of the IupDialogWrapper class..
  11. }

In another class, such as the controller class, I did a simple test, trying to invoke the method in the following way:

  1. IMDialog *frontEnd = new IMDialog();
  2. frontEnd->update(42);

The code compiles and links perfectly, but when the method "void update(int progressStatus)" is called the application terminates with an error. (actually it is not been called).

I realized that if I make another class as the Observer, which has the signature:
  1. class AnotherClass: public AbstractObserver {
  2. public:
  3. void update(int progressStatus) {
  4. cout << "AnotherClass: " << progressStatus << endl;
  5. }
  6. };

the method "void update(int progressStatus)" can be invoked, is it a problem of "multiple inheritance" or something like this? The way I'm invoking the method "frontEnd->update(42);" is wrong? I tried doing some cast, as well as dynamic_cast<>() with no sucess.

Sorry for the whole history, but I tried to explain the plot.

Thanks,
Eduardo
Reply With Quote Quick reply to this message  
Join Date: Sep 2008
Posts: 36
Reputation: mostermand is an unknown quantity at this point 
Solved Threads: 1
mostermand mostermand is offline Offline
Light Poster

Re: virtual void method() = 0; problem

 
0
  #2
Mar 29th, 2009
I don't think you can't assign values to functions/methods.

I don't know what you want to do but as I see it you use the assignment as a way to make the method do nothing until you find out how to implement the method.

To do this in C++ you can just add an empty body either in the class declaration or in the definition then you can redefine it later
All i've got is a slice of pi
Reply With Quote Quick reply to this message  
Join Date: Aug 2005
Posts: 15,442
Reputation: Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute 
Solved Threads: 1474
Team Colleague
Featured Poster
Ancient Dragon's Avatar
Ancient Dragon Ancient Dragon is offline Offline
Still Learning

Re: virtual void method() = 0; problem

 
0
  #3
Mar 29th, 2009
>>don't think you can't assign values to functions/methods.
That is how to create a pure virtual function
eduardocoelho: you need to declare the implementation of a virtual function exactly as it is in the base class, but without the "=0". The simplest way to get this right is to just copy/paste from base class to derived class.
#include "AbstractObserver.h"
#include "IupDialogWrapper.h"

class IMDialog : public AbstractObserver, public IupDialogWrapper {
public:
	virtual void update(int progressStatus) {
		cout << "IMDialog: " << progressStatus << endl;
	}

       // another methods of the IupDialogWrapper class..
}
Last edited by Ancient Dragon; Mar 29th, 2009 at 8:47 am.
Don't PM me with questions -- you might get a nasty PM in response. If you have a question then post it in one of the forums.
Reply With Quote Quick reply to this message  
Join Date: Jul 2008
Posts: 2,001
Reputation: ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of 
Solved Threads: 343
ArkM's Avatar
ArkM ArkM is offline Offline
Postaholic

Re: virtual void method() = 0; problem

 
0
  #4
Mar 29th, 2009
1. Next time use code tag with the language specifier:
[code=c++]
source(s)
[/code]
2. No need to repeate virtual specifier in derived classes.
3. >when the method "void update(int progressStatus)" is called the application terminates with an error.
Can't reproduce errors, it works as expected. No problems.
4. You must declare virtual destructor for abstract class (to invoke right derived class destructor)
5. See what you may expect from all these mechanics:
  1. class AbstractObserver {
  2. public:
  3. virtual ~AbstractObserver() {} // Add this!
  4. virtual void update(int progressStatus) = 0;
  5.  
  6. };
  7.  
  8. class AbstractSubject { // Don't know what to do with this class now...
  9. public:
  10. virtual ~AbstractSubject() {} // Add this!
  11. virtual void registerObserver(AbstractObserver* observer) = 0;
  12. virtual void removeObserver(AbstractObserver* observer) = 0;
  13. virtual void notifyObserver() = 0;
  14. };
  15.  
  16. class IMDialog : public AbstractObserver { //, public IupDialogWrapper {
  17. public:
  18. void update(int progressStatus) { // It's virtual!
  19. cout << "IMDialog: " << progressStatus << endl;
  20. }
  21. // another methods of the IupDialogWrapper class..
  22. };
  23.  
  24. class AnotherClass: public AbstractObserver {
  25. public:
  26. void update(int progressStatus) {
  27. cout << "AnotherClass: " << progressStatus << endl;
  28. }
  29. };
  30.  
  31. int main()
  32. {
  33. AbstractObserver* frontEnd = new IMDialog();
  34. frontEnd->update(42);
  35. delete frontEnd;
  36.  
  37. frontEnd = new AnotherClass();
  38. frontEnd->update(43);
  39. delete frontEnd;
  40.  
  41. return 0;
  42. }
Reply With Quote Quick reply to this message  
Join Date: Aug 2005
Posts: 15,442
Reputation: Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute 
Solved Threads: 1474
Team Colleague
Featured Poster
Ancient Dragon's Avatar
Ancient Dragon Ancient Dragon is offline Offline
Still Learning

Re: virtual void method() = 0; problem

 
0
  #5
Mar 29th, 2009
Originally Posted by ArkM View Post
1. Next time use code tag with the language specifier:
[code=c++]
source(s)
[/code]
c++ has been depreciated. use [code=cplusplus]
Don't PM me with questions -- you might get a nasty PM in response. If you have a question then post it in one of the forums.
Reply With Quote Quick reply to this message  
Join Date: Jul 2008
Posts: 2,001
Reputation: ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of 
Solved Threads: 343
ArkM's Avatar
ArkM ArkM is offline Offline
Postaholic

Re: virtual void method() = 0; problem

 
0
  #6
Mar 29th, 2009
Originally Posted by Ancient Dragon View Post
c++ has been depreciated. use [code=cplusplus]
It's a pity...
I hate this awful pseudoword ...
Reply With Quote Quick reply to this message  
Join Date: Mar 2009
Posts: 3
Reputation: eduardocoelho is an unknown quantity at this point 
Solved Threads: 0
eduardocoelho eduardocoelho is offline Offline
Newbie Poster

Re: virtual void method() = 0; problem

 
0
  #7
Mar 29th, 2009
Originally Posted by ArkM View Post
1. Next time use code tag with the language specifier:
[code=c++]
source(s)
[/code]
2. No need to repeate virtual specifier in derived classes.
3. >when the method "void update(int progressStatus)" is called the application terminates with an error.
Can't reproduce errors, it works as expected. No problems.
4. You must declare virtual destructor for abstract class (to invoke right derived class destructor)
5. See what you may expect from all these mechanics:
  1. class AbstractObserver {
  2. public:
  3. virtual ~AbstractObserver() {} // Add this!
  4. virtual void update(int progressStatus) = 0;
  5.  
  6. };
  7.  
  8. class AbstractSubject { // Don't know what to do with this class now...
  9. public:
  10. virtual ~AbstractSubject() {} // Add this!
  11. virtual void registerObserver(AbstractObserver* observer) = 0;
  12. virtual void removeObserver(AbstractObserver* observer) = 0;
  13. virtual void notifyObserver() = 0;
  14. };
  15.  
  16. class IMDialog : public AbstractObserver { //, public IupDialogWrapper {
  17. public:
  18. void update(int progressStatus) { // It's virtual!
  19. cout << "IMDialog: " << progressStatus << endl;
  20. }
  21. // another methods of the IupDialogWrapper class..
  22. };
  23.  
  24. class AnotherClass: public AbstractObserver {
  25. public:
  26. void update(int progressStatus) {
  27. cout << "AnotherClass: " << progressStatus << endl;
  28. }
  29. };
  30.  
  31. int main()
  32. {
  33. AbstractObserver* frontEnd = new IMDialog();
  34. frontEnd->update(42);
  35. delete frontEnd;
  36.  
  37. frontEnd = new AnotherClass();
  38. frontEnd->update(43);
  39. delete frontEnd;
  40.  
  41. return 0;
  42. }
mostermand:
I'm defining a pure virtual function, as explained by Ancient Dragon.

Ancient Dragon:
The fact or including the "virtual" specifier in front of the method signature didn't make it to work.

ArkM:
Thanks, you'll follow your advices when posting a new thread.
I added the virtual destructors as you suggested, but I think it is not the main point. I still have no sucess while trying to invoke the "update" method.
I tried to declare the object front end in the way you suggested, such as:

  1. AbstractObserver* frontEnd = new IMDialog();

I am still getting no success. As I can see, you redefined the "IMDialog" class in a different way that makes no sens for my application, you removed the " public IupDialogWrapper {" inheritance definition, but this class specifies my user interface an I have to extend it.
As I said, if I have a simple class which simples extends the "AbstractObserver" abstract class it works well, I already tested it. The problem is that the "IMDialog" must extends both "AbstractObserver" and "IupDialogWrapper" classes, wouldn't it be causing the problem?

Thanks,
Eduardo
Reply With Quote Quick reply to this message  
Join Date: Mar 2009
Posts: 3
Reputation: eduardocoelho is an unknown quantity at this point 
Solved Threads: 0
eduardocoelho eduardocoelho is offline Offline
Newbie Poster

Re: virtual void method() = 0; problem

 
0
  #8
Mar 29th, 2009
I'll post all the class codes so that it becomes clearer to understand:

My compiler version: gcc version 3.4.5 (mingw-vista special r3).

My super-classes are:

AbstractObserver.h
  1. class AbstractObserver {
  2. public:
  3. virtual void update(int progressStatus) = 0;
  4. };

AbstractSubject.h
  1. #include "AbstractObserver.h"
  2.  
  3. class AbstractSubject {
  4. public:
  5.  
  6. virtual void registerObserver(AbstractObserver* observer) = 0;
  7.  
  8. virtual void removeObserver(AbstractObserver* observer) = 0;
  9.  
  10. virtual void notifyObserver() = 0;
  11. };


IupDialogWrapper.h
  1. // This class is a wrapper for the User interface API that I'm using which need C callbacks (that I
  2. // implemented as friend functions.
  3. #include <stdlib.h>
  4. #include <iostream>
  5. #include <iup.h>
  6. #include "IMDefs.h"
  7.  
  8. using namespace std;
  9.  
  10. namespace view {
  11.  
  12. class IupDialogWrapper {
  13. public:
  14. // constructors..
  15.  
  16. protected:
  17. // some class attributes..
  18. // some class member functions, Ex:
  19. void showDialog(int x, int y);
  20. virtual int callbackResize(Ihandle *self, int w, int h) { return IUP_DEFAULT; }
  21. virtual int callbackShow(Ihandle *self, int state) { return IUP_DEFAULT; }
  22.  
  23. private:
  24. friend int IMV_IupDialogWrapper_callbackDialogResize(Ihandle* self, int w, int h);
  25. };
  26. }

IupDialogWrapper.cpp
  1. #include "IupDialogWrapper.h"
  2. #include "Controller.h"
  3.  
  4. namespace view {
  5.  
  6. void IupDialogWrapper::showDialog(int x, int y) { /* code.. */ }
  7.  
  8. int IMV_IupDialogWrapper_callbackDialogResize(Ihandle *self, int w, int h) { /* code.. */ }
  9.  
  10. // The virtual member functions are defined in the subclass (see IMDialog class below)
  11. }


The classes who extends these abstract classes are:

IMDialog.h
  1. #include "AbstractObserver.h"
  2. #include "IupDialogWrapper.h"
  3.  
  4. namespace view {
  5. class IMDialog : public AbstractObserver, public IupDialogWrapper {
  6. public:
  7. void update(int progressStatus); // supposed to be from AbstractObserver abstract class
  8.  
  9. protected:
  10. int callbackResize(Ihandle *self, int w, int h);
  11. int callbackShow(Ihandle *self, int state);
  12. };
  13. }

IMDialog.cpp
  1. #include "IMDialog.h"
  2. #include "Utils.h"
  3.  
  4. namespace view {
  5. int IMDialog::callbackResize(Ihandle *self, int w, int h) { /* code.. */ }
  6. int IMDialog::callbackShow(Ihandle *self, int state) { /* code.. */ }
  7. }
  8.  
  9. void IMDialog::update(int progressStatus) {
  10. cout << "IMDialog: " << progressStatus << endl;
  11. }
  12. }


Mosaic.h // this class is running ok, but I'll post here just for clarification
  1. #include "AbstractSubject.h"
  2.  
  3. using namespace std;
  4.  
  5. namespace model {
  6. class Mosaic : public AbstractSubject {
  7. public:
  8. // constructors..etc
  9.  
  10. void registerObserver(AbstractObserver* observer);
  11. void removeObserver(AbstractObserver* observer);
  12.  
  13. private:
  14. void notifyObserver();
  15.  
  16. private:
  17. list<AbstractObserver* > observers;
  18. };
  19. }

Mosaic.cpp
  1. #include "Mosaic.h"
  2.  
  3. using namespace std;
  4.  
  5. namespace model {
  6. void Mosaic::registerObserver(AbstractObserver* observer) {
  7. this->observers.push_back(observer);
  8. }
  9.  
  10. void Mosaic::removeObserver(AbstractObserver* observer) {
  11. this->observers.remove(observer);
  12. }
  13.  
  14. void Mosaic::notifyObserver() {
  15. list<AbstractObserver*>::iterator it = this->observers.begin();
  16. while (it != this->observers.end()) {
  17.  
  18. // HERE IS THE PROBLEM!!!!!!!
  19. // The method below is not being called!
  20. // If the IMDialog class only inherits from AbstractObserver it works, but since it
  21. // also inherits from IupDialogWrapper it seem's not be working!
  22.  
  23. ((AbstractObserver*) (*it))->update(this->mosaicingProgressStatus);
  24. ++it;
  25. }
  26.  
  27. }
  28. }

The IMDialog class instantiation as well as registering inside the Mosaic object is as follows

Controller.h
  1. #include "IMDialog.h"
  2. namespace view {
  3. class IMDialog;
  4. }
  5. #include "AbstractObserver.h"
  6. #include "Mosaic.h"
  7.  
  8. namespace controller {
  9. class Controller {
  10. public:
  11. // constructors, etc
  12. bool createMosaic(/* parameters */);
  13.  
  14. private:
  15. AbstractObserver *frontEnd;
  16. };
  17. }


Controller.cpp
  1. #include "Controller.h"
  2.  
  3. namespace controller {
  4. bool Controller::createMosaic(/* parameters */ ) {
  5.  
  6. this->frontEnd = new view::IMDialog(this);
  7. this->mosaic = new model::Mosaic(/* parameters */);
  8.  
  9. // !!!
  10. // Registering the frontEnd object as a observer o the Mosaic object.
  11. // The mosaic object in a future time will start some processing and consequently
  12. // will try to call the "update" method of the frontEnd object (as described inside the "void
  13. // Mosaic::notifyObserver() {} method"
  14. this->mosaic->registerObserver(this->frontEnd);
  15.  
  16. // I also tried to make a simple call here inside this method, such as:
  17. frontEnd->update(42);
  18.  
  19. // but it didn't work (of course, if it works here it will work inside the "void Mosaic::notifyObserver() {} method" too
  20.  
  21. // some application stuff..
  22. return this->mosaic->create();
  23. }
  24. }


Well, It seems like a lot of code, maybe there's another way to explain what I trying to do, I posted all the code in order not to miss any information about the #includes and method/classes signatures.
I'm compiling and linking with sucess:

============================================
g++ -IC:\tcc\dev\libs\eclipse\iup3_0_beta2_Win32_mingw3_lib\include -IC:\tcc\dev\libs\eclipse\cd5_1_1_Win32_mingw3_lib\include -IC:\tcc\dev\libs\eclipse\im3_4_1_Win32_mingw3_lib\include -O0 -g3 -Wall -c -fmessage-length=0 -osrc\Mosaic.o ..\src\Mosaic.cpp

// ...
// another source files compilation, similarly

g++ -LC:\tcc\dev\libs\eclipse\iup3_0_beta2_Win32_mingw3_lib -LC:\tcc\dev\libs\eclipse\cd5_1_1_Win32_mingw3_lib -LC:\tcc\dev\libs\eclipse\im3_4_1_Win32_mingw3_lib -oImageMosaicing.exe src2\MatrixTemplate.o src2\ImageMosaicing.o src2\IMMosaic.o src\main.o src\Vector.o src\Mosaic.o src\Matrix.o src\ManipulableObject.o src\IupDialogWrapper.o src\IMImage.o src\IMDialog.o src\Homography.o src\CorrespondencePointMark.o src\CorrespondencePoint.o src\Controller.o -liupcd -lcd -liup -lgdi32 -lcomctl32 -lole32 -lcomdlg32 -lfreetype6 -lim
Build complete for project ImageMosaicing
Time consumed: 7751 ms.
============================================

The problem occurs in runtime !

Best regards,
Eduardo

Originally Posted by eduardocoelho View Post
mostermand:
I'm defining a pure virtual function, as explained by Ancient Dragon.

Ancient Dragon:
The fact or including the "virtual" specifier in front of the method signature didn't make it to work.

ArkM:
Thanks, you'll follow your advices when posting a new thread.
I added the virtual destructors as you suggested, but I think it is not the main point. I still have no sucess while trying to invoke the "update" method.
I tried to declare the object front end in the way you suggested, such as:

  1. AbstractObserver* frontEnd = new IMDialog();

I am still getting no success. As I can see, you redefined the "IMDialog" class in a different way that makes no sens for my application, you removed the " public IupDialogWrapper {" inheritance definition, but this class specifies my user interface an I have to extend it.
As I said, if I have a simple class which simples extends the "AbstractObserver" abstract class it works well, I already tested it. The problem is that the "IMDialog" must extends both "AbstractObserver" and "IupDialogWrapper" classes, wouldn't it be causing the problem?

Thanks,
Eduardo
Reply With Quote Quick reply to this message  
Join Date: Jul 2008
Posts: 2,001
Reputation: ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of 
Solved Threads: 343
ArkM's Avatar
ArkM ArkM is offline Offline
Postaholic

Re: virtual void method() = 0; problem

 
0
  #9
Mar 29th, 2009
>I also tried to make a simple call here inside this method, such as: frontEnd->update(42); but it didn't work
The fact that IMDialog also inherits from the IupDialogWrapper does not bear a relation to its is_an AbstractObserver characteristic. The fact that no visual effect after update call does not bear a relation to this polymorphic mechanics. For example, may be it's an error in your indirect path to the visual interface.
Regrettably, it didn't work is not a diagnosis, it's a vague symptom only.

Once again: define an abstact class destructor as virtual!!!

I'll try to analyse your code later...
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:


Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC