Thread: Parent/child object design

  1. #1
    Amateur
    Join Date
    Sep 2003
    Posts
    228

    Parent/child object design

    Well, I would like to make a OO design for a simple windowing system.

    But my problem is actually that I cannot create a parent/children management system. I have an interface (pure abstract) and an implmentation-help class, but when it comes to setting the Windows' handle (HWND) of a window, I have to access the implementation through my interface. I could use a dynamic_cast but there is another problem, my parent window inherit the implmentation class with private access so I cannot upcast the pointer from outside this parent class.

    How can I provide a general way of retrieving the handle (which is declared in the implmentation base class) from an interface I don't know the real type of?

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Maybe I don't understand your question but it seems all you need is a member function, ie:

    virtual HWND & handle()
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  3. #3
    Amateur
    Join Date
    Sep 2003
    Posts
    228
    Well, I don't want such a function, I just want the interface to be all the user can see.

  4. #4
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Would you mind giving an example?
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  5. #5
    Amateur
    Join Date
    Sep 2003
    Posts
    228
    Probably am I not clear enough. ^^ So here's an example, it is not the real code but just to explain the problem:

    I have a pure abstract base class which serve as an interface.
    Code:
    class Window : public Object {
    public:
        Window() throw() {}
        virtual ~Window() throw() {}
    
        // other members
    
        virtual Window *GetParent() const throw() = 0;
        virtual void SetParent(Window *pNewParent) throw() = 0;
        virtual void ChangeParent() throw() = 0;
    
        virtual Window *FindChild(PSTR pCaption) const throw() = 0;
        virtual void AddChild(Window *pChild) throw() = 0;
        virtual void RemoveChild(Window *pChild) throw() = 0;
    };
    And now I have the real class:
    Code:
    // a pure helper interface which provides with the implementation
    class Win32Window {
    protected:
        Win32Window() throw() {}
        virtual ~Win32Window() throw() {}
    
        // other members
    
        // should I put the parent/child stuffs here?
        // in this case, it would be
        void SetParent(Win32Window *pNewParent) throw()  // sets the parent window
        {
            this->pParent = pNewParent;  // no problem here
                                         // but how can I get the handle
                                         // to my parent window from my interface?
                                         // maybe a cast but...
        }
    
        void Create() throw(Exceptions::System)  // create the window
        {
            this->Handle = CreateWindowEx(ExtendedStyle,
                                          pClassName,
                                          pCaption,
                                          Style,
                                          Left, Top,
                                          Width, Height,
                                          // no problem for now
                                          pParent->GetHandle(),
                                          hMenu,
                                          hGlobalInstance,
                                          NULL);
        }
    
        // helper functions that access the private members
        INT GetStyle() const throw() { return this->Style; }
        void SetStyle(INT NewStyle) throw() { this->Style = NewStyle; }
    
    private:
        Win32Window *pParent;
    };
    
    // here is a derived class from Win32Window, it serves as a base frame window
    class Frame : public Window, private Win32Window {
    public:
        Frame() throw() {}
        virtual ~Frame() throw() {}
    
        // all inherited members
        // virtual members as well
    
        // binds the interface with the implementation
        void SetParent(Win32Window *pNewParent) throw()
        {
            Win32Window::SetParent(/* what should I do? */
                                   // I could do a cast... I don't know if it would work
                                   // but I shouldn't,
                                   // because I don't know if the real class provides
                                   // a full interface compatibility with its implementation
                                   // that is to say Win32Window
                                   // besides, it probably does not as that class is to be
                                   // privately inherited...
                                   dynamic_cast<Win32Window *>(pNewParent)
                                   );
        }
    
    protected:
        using Win32Window::GetStyle() const throw();  // there is only the read accessor
                                                      // because I want the style
                                                      // to be the same for all
                                                      // frame windows
    };
    
    // even if I added a GetHandle() method, I couldn't just access it as it would
    // be in Win32Window...

  6. #6
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Well, as long as you use virtual functions, there's no reason to use a dynamic_cast, since the vtable will direct function invocations to the correct piece of code.

    Is that what you were asking?
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  7. #7
    Amateur
    Join Date
    Sep 2003
    Posts
    228
    No, but I think I finally found a solution to my problem, thanks anyway for trying to help. ^^

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. any comments about a cache design?
    By George2 in forum C Programming
    Replies: 6
    Last Post: 09-14-2006, 12:53 PM
  2. Implementing Inheritence into your design
    By bobthebullet990 in forum C++ Programming
    Replies: 6
    Last Post: 08-05-2006, 04:40 PM
  3. A question about constructors...
    By Wolve in forum C++ Programming
    Replies: 9
    Last Post: 05-04-2005, 04:24 PM
  4. Object Oriented Design help!! ;(
    By cpp4ever in forum C++ Programming
    Replies: 3
    Last Post: 12-03-2001, 11:16 AM