CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    Mar 2009
    Posts
    3

    virtual void method() = 0; problem

    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")

    ////////////////////////////////
    class AbstractObserver {
    public:
    virtual void update(int progressStatus) = 0;

    };
    ////////////////////////////////

    ////////////////////////////////
    class AbstractSubject {
    public:
    virtual void registerObserver(AbstractObserver* observer) = 0;
    virtual void removeObserver(AbstractObserver* observer) = 0;
    virtual void notifyObserver() = 0;
    };
    ////////////////////////////////

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

    ////////////////////////////////
    #include "AbstractObserver.h"
    #include "IupDialogWrapper.h"

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

    // another methods of the IupDialogWrapper class..
    }
    ////////////////////////////////

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

    ////////////////////////////////
    IMDialog *frontEnd = new IMDialog();
    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:


    ////////////////////////////////
    class AnotherClass: public AbstractObserver {
    public:
    void update(int progressStatus) {
    cout << "AnotherClass: " << progressStatus << endl;
    }
    };
    ////////////////////////////////

    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

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: virtual void method() = 0; problem

    Quote Originally Posted by eduardocoelho View Post
    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.
    1) I'm sure those threads explained what code tags are. Please use code tags when posting code.

    2) Please post the simplest, smallest, but full program that demonstrates the error. This way, no one has to invent code to duplicate your problem.

    Given the code you posted, this is a full program that does not demonstrate the error.
    Code:
    #include <iostream>
    
    class AbstractObserver 
    {
        public:
            virtual void update(int progressStatus) = 0;
    };
    
    class AbstractSubject 
    {
        public:
            virtual void registerObserver(AbstractObserver* observer) = 0;
            virtual void removeObserver(AbstractObserver* observer) = 0;
            virtual void notifyObserver() = 0;
    };
    
    class IMDialog : public AbstractObserver
    {
        public:
            void update(int progressStatus) 
            {
                std::cout << "IMDialog: " << progressStatus << std::endl;
            }
    };
    
    int main()
    {
        IMDialog frontEnd;
        frontEnd.update(42);
    }
    Since you didn't post what IupDialogWrapper is, that is all the information available. This program prints 42 correctly.
    I have experience with Java/OO programming
    Is that why you instinctively used "new" to create your object in your example? Hopefully you realize that "new" in C++ is not the same thing as "new" in Java, with the former being unnecessary in your example.

    Regards,

    Paul McKenzie

  3. #3
    Join Date
    Mar 2009
    Posts
    3

    Re: virtual void method() = 0; problem

    Paul McKenzie:
    Ok, you'll follow your advices when posting a new thread, thanks for the advices!

    I agree that your suggested program works well and prints 42 correctly. But It seems that you forgot the case that the IMDialog class signature is

    Code:
    class IMDialog : public AbstractObserver, public IupDialogWrapper {
    As I said, I already made a test as you defined, by creating a class that simply extends one class, the "AbstractObserver" abstract class, but my class, called "IMDialog" must extend both "AbstractObserver" and "IupDialogWrapper" classes, since the "IupDialogWrapper" defines how my front-end is, some piece of code:

    Code:
    class IupDialogWrapper {
    public:
    
    	IupDialogWrapper();
    
           virtual ~IupDialogWrapper();
    
           virtual int callbackResize(Ihandle *self, int w, int h);
    
           virtual int callbackShow(Ihandle *self, int state);
    
           // Another methods that I override in the IMDialog class
    };
    I post the whole story in order to explain what I trying to do (in this case, implement the Observer Pattern in C++), I didn't want to cause confusion, next thread I'll pay more attention on this issue and try to be more directly.

    Eduardo

  4. #4
    Join Date
    Apr 1999
    Posts
    27,449

    Re: virtual void method() = 0; problem

    Quote Originally Posted by eduardocoelho View Post
    But It seems that you forgot the case that the IMDialog class signature is
    I didn't forget. I didn't want to invent code that you didn't post.

    That's the reason why I stated that you should post a full example first, and not leave it to others to try and duplicate your error by inventing code samples. That ends up wasting time and effort for people who are trying to help.

    So go to the example that I posted. Take it and add something that duplicates the error that you are describing. Then repost that example, along with the exact compiler error that you are receiving (as well as the compiler you're using and version).

    There is no need to go into long explanations as to what you're doing -- we're just looking at C++ code and compiler error, so it doesn't matter what the final application is supposed to be doing or what design pattern you're implementing.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; March 29th, 2009 at 11:09 AM.

  5. #5
    Join Date
    Mar 2009
    Posts
    3

    Re: virtual void method() = 0; problem

    Ok,

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

    My super-classes are:

    AbstractObserver.h
    Code:
    class AbstractObserver {
    public:
        virtual void update(int progressStatus) = 0;
    };
    AbstractSubject.h
    Code:
    #include "AbstractObserver.h"
    
    class AbstractSubject {
    public:
    	
    	virtual void registerObserver(AbstractObserver* observer) = 0;
    
    	virtual void removeObserver(AbstractObserver* observer) = 0;
    
    	virtual void notifyObserver() = 0;
    };

    IupDialogWrapper.h
    Code:
    // This class is a wrapper for the User interface API that I'm using which need C callbacks (that I 
    // implemented as friend functions.
    #include <stdlib.h>
    #include <iostream>
    #include <iup.h>
    #include "IMDefs.h"
    
    using namespace std;
    
    namespace view {
    
    class IupDialogWrapper {
    public:
    // constructors..
    
    protected:
           // some class attributes..
           // some class member functions, Ex:
           void showDialog(int x, int y);
           virtual int callbackResize(Ihandle *self, int w, int h) { return IUP_DEFAULT; }
           virtual int callbackShow(Ihandle *self, int state) { return IUP_DEFAULT; }
           
    private:
           friend int IMV_IupDialogWrapper_callbackDialogResize(Ihandle* self, int w, int h);
    };
    }
    IupDialogWrapper.cpp
    Code:
    #include "IupDialogWrapper.h"
    #include "Controller.h"
    
    namespace view {
    
    void IupDialogWrapper::showDialog(int x, int y) { /* code.. */ }
    
    int IMV_IupDialogWrapper_callbackDialogResize(Ihandle *self, int w, int h) {  /* code.. */ }
    
    // The virtual member functions are defined in the subclass (see IMDialog class below)
    }

    The classes who extends these abstract classes are:

    IMDialog.h
    Code:
    #include "AbstractObserver.h"
    #include "IupDialogWrapper.h"
    
    namespace view {
    class IMDialog : public AbstractObserver, public IupDialogWrapper {
    public:
    void update(int progressStatus); // supposed to be from AbstractObserver abstract class
    
    protected:
    int callbackResize(Ihandle *self, int w, int h);
    int callbackShow(Ihandle *self, int state);
    };
    }
    IMDialog.cpp
    Code:
    #include "IMDialog.h"
    #include "Utils.h"
    
    namespace view {
    int IMDialog::callbackResize(Ihandle *self, int w, int h) { /* code.. */  }
    int IMDialog::callbackShow(Ihandle *self, int state) { /* code.. */  }
    }
    
    void IMDialog::update(int progressStatus) {
    	cout << "IMDialog: " << progressStatus << endl;
    }
    }

    Mosaic.h // this class is running ok, but I'll post here just for clarification
    Code:
    #include "AbstractSubject.h"
    
    using namespace std;
    
    namespace model {
    class Mosaic : public AbstractSubject {
    public:
           // constructors..etc
    
           void registerObserver(AbstractObserver* observer);
           void removeObserver(AbstractObserver* observer);
    
    private:	
    	void notifyObserver();
    
    private:
            list<AbstractObserver* > observers;
    };
    }
    Mosaic.cpp
    Code:
    #include "Mosaic.h"
    
    using namespace std;
    
    namespace model {
    void Mosaic::registerObserver(AbstractObserver* observer) {
    	this->observers.push_back(observer);
    }
    
    void Mosaic::removeObserver(AbstractObserver* observer) {
    	this->observers.remove(observer);
    }
    
    void Mosaic::notifyObserver() {
    	list<AbstractObserver*>::iterator it = this->observers.begin();
    	while (it != this->observers.end()) {
                   
    // HERE IS THE PROBLEM!!!!!!!
    // The method below is not being called!
    // If the IMDialog class only inherits from AbstractObserver it works, but since it
    // also inherits from IupDialogWrapper it seem's not be working!
                   
    		((AbstractObserver*) (*it))->update(this->mosaicingProgressStatus);
    		++it;
    	}
    
    }
    }
    The IMDialog class instantiation as well as registering inside the Mosaic object is as follows

    Controller.h
    Code:
    #include "IMDialog.h"
    namespace view {
    	class IMDialog;
    }
    #include "AbstractObserver.h"
    #include "Mosaic.h"
    
    namespace controller {
    class Controller {
    public:
         // constructors, etc
         bool createMosaic(/* parameters */);
    
    private:
    	AbstractObserver *frontEnd;
    };
    }

    Controller.cpp
    Code:
    #include "Controller.h"
    
    namespace controller {
    bool Controller::createMosaic(/* parameters */ ) {
    
            this->frontEnd = new view::IMDialog(this);
    	this->mosaic = new model::Mosaic(/* parameters */);
    
    // !!!
    // Registering the frontEnd object as a observer o the Mosaic object.
    // The mosaic object in a future time will start some processing and consequently 
    // will try to call the "update" method of the frontEnd object (as described inside the "void
    // Mosaic::notifyObserver() {} method"
    	this->mosaic->registerObserver(this->frontEnd);
    
    // I also tried to make a simple call here inside this method, such as:
           frontEnd->update(42);
    
    // but it didn't work (of course, if it works here it will work inside the "void Mosaic::notifyObserver() {} method" too
    
    // some application stuff..
    	return this->mosaic->create();
    }
    }

    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

  6. #6
    Join Date
    Apr 1999
    Posts
    27,449

    Re: virtual void method() = 0; problem

    Quote Originally Posted by eduardocoelho View Post
    Ok,

    Compiler: gcc version 3.4.5 (mingw-vista special r3).
    First, gcc is up to version 4.x.

    Second, instead of posting all of this, why not take 10 steps back and start with the example that I posted? What would make that example not "work" correctly? If it's a problem with multiple inheritance, then just create a simple example and show that it is a problem with multiple inheritance. I did 95&#37; of the work already -- just add to it. Every C++ issue can be duplicated with simple code.

    That is the what any good C++ programmer would do. Start with a simple example, and make sure that they can duplicate the problem with that simple example. No good C++ programmer takes a full blown application to diagnose a compiler error. Not only that, there is no way for anyone to get this to compile and run, as all of those include files are not there. Also, there is no main() function to run anything or show how you're starting this whole thing.

    Please follow these guidelines:

    http://www.parashift.com/c++-faq-lit...t.html#faq-5.8

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; March 29th, 2009 at 04:05 PM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured