Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. how to design multiple inheritance classes?

how to design multiple inheritance classes?

Scheduled Pinned Locked Moved C / C++ / MFC
designooptutorialquestion
17 Posts 7 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N nm_114

    Christian Graus wrote: Then derive from a common base class that contains those variables I made a struct WFIOInfo that has the handle info etc. and CWinFileIn and CWinFileOut both derive from it, so if CWinFileInOut derive from both CWinFileIn and CWinFileOut which both have their own instances of the base class i still get the same ambiguous errors. Or did I not understand what you were suggesting? Christian Graus wrote: and/or derive from multiple classes that define interfaces I don't know what that means. do you know of any examples i could look at?

    S Offline
    S Offline
    sunit5
    wrote on last edited by
    #8

    go for virtual base class

    1 Reply Last reply
    0
    • C Christian Graus

      struct WFIOInfo { ... } class WinFileInInterface // Note - NOT derived from WFIOInfo, defines an interface for what CWinFIleIn has that WFIOInfo does not { virtual void myMethod; //etc } class WinFileOutInterface { virtual void myMethod; //etc } class CWinFileIn : WFIOInfo, WinFileInInterface { } class CWinFileOut : WFIOInfo, WinFileOutInterface { } class CWinFileInOut : WFINInfo, WinFileInInterface, WinFileOutInterface { } So, CWinFileInOut is not derived from either derived class, but from all three base classes that combine to make the class you're after. Christian Graus - Microsoft MVP - C++

      N Offline
      N Offline
      nm_114
      wrote on last edited by
      #9

      ok, i think i *almost* have it, but its giving me the following errors:

      Linking...
      winiotest.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall WinFileOutInterface::DoWriteFile(void const *,unsigned long)" (?DoWriteFile@WinFileOutInterface@@UAEHPBXK@Z)
      winiotest.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall WinFileInInterface::DoReadFile(void *,unsigned long)" (?DoReadFile@WinFileInInterface@@UAEHPAXK@Z)
      winiotest.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall WinFileInInterface::Open(char const *)" (?Open@WinFileInInterface@@UAEHPBD@Z)
      winiotest.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall WinFileOutInterface::Open(char const *)" (?Open@WinFileOutInterface@@UAEHPBD@Z)
      Debug/winiotest.exe : fatal error LNK1120: 4 unresolved externals

      here's my code so far:

      struct WFIOInfo
      {
      	HANDLE m_hFile;
      	DWORD m_dwBytes;
      };
      
      class WinFileInInterface
      {
      public:
      	virtual BOOL Open(LPCTSTR lpszFileName);
      	virtual BOOL DoReadFile(LPVOID lpBuffer, DWORD nNumberOfBytesToRead);
      };
      
      class WinFileOutInterface
      {
      public:
      	virtual BOOL Open(LPCTSTR lpszFileName);
      	virtual BOOL DoWriteFile(LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite);
      };
      
      class CWinFileIn : WFIOInfo, WinFileInInterface
      {
      public:
      	virtual BOOL Open(LPCTSTR lpszFileName)
      	{
      		return TRUE;
      	}
      	virtual BOOL DoReadFile(LPVOID lpBuffer, DWORD nNumberOfBytesToRead)
      	{
      		return ::ReadFile(m_hFile, lpBuffer, nNumberOfBytesToRead, &m_dwBytes, NULL);
      	}
      };
      
      class CWinFileOut : WFIOInfo, WinFileOutInterface
      {
      public:
      	virtual BOOL Open(LPCTSTR lpszFileName)
      	{
      		return TRUE;
      	}
      	virtual BOOL DoWriteFile(LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite)
      	{
      		return ::WriteFile(m_hFile, lpBuffer, nNumberOfBytesToWrite, &m_dwBytes, NULL);
      	}
      };
      
      class CWinFileInOut : WFIOInfo, WinFileInInterface, WinFileOutInterface
      {
      public:
      	BOOL Open(LPCTSTR lpszFileName)
      	{
      		return TRUE;
      	}
      };
      

      any idea what i'm doing wrong?

      G V B 3 Replies Last reply
      0
      • N nm_114

        ok, i think i *almost* have it, but its giving me the following errors:

        Linking...
        winiotest.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall WinFileOutInterface::DoWriteFile(void const *,unsigned long)" (?DoWriteFile@WinFileOutInterface@@UAEHPBXK@Z)
        winiotest.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall WinFileInInterface::DoReadFile(void *,unsigned long)" (?DoReadFile@WinFileInInterface@@UAEHPAXK@Z)
        winiotest.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall WinFileInInterface::Open(char const *)" (?Open@WinFileInInterface@@UAEHPBD@Z)
        winiotest.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall WinFileOutInterface::Open(char const *)" (?Open@WinFileOutInterface@@UAEHPBD@Z)
        Debug/winiotest.exe : fatal error LNK1120: 4 unresolved externals

        here's my code so far:

        struct WFIOInfo
        {
        	HANDLE m_hFile;
        	DWORD m_dwBytes;
        };
        
        class WinFileInInterface
        {
        public:
        	virtual BOOL Open(LPCTSTR lpszFileName);
        	virtual BOOL DoReadFile(LPVOID lpBuffer, DWORD nNumberOfBytesToRead);
        };
        
        class WinFileOutInterface
        {
        public:
        	virtual BOOL Open(LPCTSTR lpszFileName);
        	virtual BOOL DoWriteFile(LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite);
        };
        
        class CWinFileIn : WFIOInfo, WinFileInInterface
        {
        public:
        	virtual BOOL Open(LPCTSTR lpszFileName)
        	{
        		return TRUE;
        	}
        	virtual BOOL DoReadFile(LPVOID lpBuffer, DWORD nNumberOfBytesToRead)
        	{
        		return ::ReadFile(m_hFile, lpBuffer, nNumberOfBytesToRead, &m_dwBytes, NULL);
        	}
        };
        
        class CWinFileOut : WFIOInfo, WinFileOutInterface
        {
        public:
        	virtual BOOL Open(LPCTSTR lpszFileName)
        	{
        		return TRUE;
        	}
        	virtual BOOL DoWriteFile(LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite)
        	{
        		return ::WriteFile(m_hFile, lpBuffer, nNumberOfBytesToWrite, &m_dwBytes, NULL);
        	}
        };
        
        class CWinFileInOut : WFIOInfo, WinFileInInterface, WinFileOutInterface
        {
        public:
        	BOOL Open(LPCTSTR lpszFileName)
        	{
        		return TRUE;
        	}
        };
        

        any idea what i'm doing wrong?

        G Offline
        G Offline
        GDavy
        wrote on last edited by
        #10

        an interface should be purely abstract so put a =0 behind function definitions. class WinFileInInterface { public: virtual BOOL Open(LPCTSTR lpszFileName) = 0; virtual BOOL DoReadFile(LPVOID lpBuffer, DWORD nNumberOfBytesToRead) = 0; }; class WinFileOutInterface { public: virtual BOOL Open(LPCTSTR lpszFileName) = 0; virtual BOOL DoWriteFile(LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite) = 0; };

        N 1 Reply Last reply
        0
        • N nm_114

          ok, i think i *almost* have it, but its giving me the following errors:

          Linking...
          winiotest.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall WinFileOutInterface::DoWriteFile(void const *,unsigned long)" (?DoWriteFile@WinFileOutInterface@@UAEHPBXK@Z)
          winiotest.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall WinFileInInterface::DoReadFile(void *,unsigned long)" (?DoReadFile@WinFileInInterface@@UAEHPAXK@Z)
          winiotest.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall WinFileInInterface::Open(char const *)" (?Open@WinFileInInterface@@UAEHPBD@Z)
          winiotest.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall WinFileOutInterface::Open(char const *)" (?Open@WinFileOutInterface@@UAEHPBD@Z)
          Debug/winiotest.exe : fatal error LNK1120: 4 unresolved externals

          here's my code so far:

          struct WFIOInfo
          {
          	HANDLE m_hFile;
          	DWORD m_dwBytes;
          };
          
          class WinFileInInterface
          {
          public:
          	virtual BOOL Open(LPCTSTR lpszFileName);
          	virtual BOOL DoReadFile(LPVOID lpBuffer, DWORD nNumberOfBytesToRead);
          };
          
          class WinFileOutInterface
          {
          public:
          	virtual BOOL Open(LPCTSTR lpszFileName);
          	virtual BOOL DoWriteFile(LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite);
          };
          
          class CWinFileIn : WFIOInfo, WinFileInInterface
          {
          public:
          	virtual BOOL Open(LPCTSTR lpszFileName)
          	{
          		return TRUE;
          	}
          	virtual BOOL DoReadFile(LPVOID lpBuffer, DWORD nNumberOfBytesToRead)
          	{
          		return ::ReadFile(m_hFile, lpBuffer, nNumberOfBytesToRead, &m_dwBytes, NULL);
          	}
          };
          
          class CWinFileOut : WFIOInfo, WinFileOutInterface
          {
          public:
          	virtual BOOL Open(LPCTSTR lpszFileName)
          	{
          		return TRUE;
          	}
          	virtual BOOL DoWriteFile(LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite)
          	{
          		return ::WriteFile(m_hFile, lpBuffer, nNumberOfBytesToWrite, &m_dwBytes, NULL);
          	}
          };
          
          class CWinFileInOut : WFIOInfo, WinFileInInterface, WinFileOutInterface
          {
          public:
          	BOOL Open(LPCTSTR lpszFileName)
          	{
          		return TRUE;
          	}
          };
          

          any idea what i'm doing wrong?

          V Offline
          V Offline
          vikramlinux
          wrote on last edited by
          #11

          Why dont u use classname as specifier? like ObjectInstanceName.Classname::variablename?

          1 Reply Last reply
          0
          • N nm_114

            ok, i think i *almost* have it, but its giving me the following errors:

            Linking...
            winiotest.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall WinFileOutInterface::DoWriteFile(void const *,unsigned long)" (?DoWriteFile@WinFileOutInterface@@UAEHPBXK@Z)
            winiotest.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall WinFileInInterface::DoReadFile(void *,unsigned long)" (?DoReadFile@WinFileInInterface@@UAEHPAXK@Z)
            winiotest.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall WinFileInInterface::Open(char const *)" (?Open@WinFileInInterface@@UAEHPBD@Z)
            winiotest.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall WinFileOutInterface::Open(char const *)" (?Open@WinFileOutInterface@@UAEHPBD@Z)
            Debug/winiotest.exe : fatal error LNK1120: 4 unresolved externals

            here's my code so far:

            struct WFIOInfo
            {
            	HANDLE m_hFile;
            	DWORD m_dwBytes;
            };
            
            class WinFileInInterface
            {
            public:
            	virtual BOOL Open(LPCTSTR lpszFileName);
            	virtual BOOL DoReadFile(LPVOID lpBuffer, DWORD nNumberOfBytesToRead);
            };
            
            class WinFileOutInterface
            {
            public:
            	virtual BOOL Open(LPCTSTR lpszFileName);
            	virtual BOOL DoWriteFile(LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite);
            };
            
            class CWinFileIn : WFIOInfo, WinFileInInterface
            {
            public:
            	virtual BOOL Open(LPCTSTR lpszFileName)
            	{
            		return TRUE;
            	}
            	virtual BOOL DoReadFile(LPVOID lpBuffer, DWORD nNumberOfBytesToRead)
            	{
            		return ::ReadFile(m_hFile, lpBuffer, nNumberOfBytesToRead, &m_dwBytes, NULL);
            	}
            };
            
            class CWinFileOut : WFIOInfo, WinFileOutInterface
            {
            public:
            	virtual BOOL Open(LPCTSTR lpszFileName)
            	{
            		return TRUE;
            	}
            	virtual BOOL DoWriteFile(LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite)
            	{
            		return ::WriteFile(m_hFile, lpBuffer, nNumberOfBytesToWrite, &m_dwBytes, NULL);
            	}
            };
            
            class CWinFileInOut : WFIOInfo, WinFileInInterface, WinFileOutInterface
            {
            public:
            	BOOL Open(LPCTSTR lpszFileName)
            	{
            		return TRUE;
            	}
            };
            

            any idea what i'm doing wrong?

            B Offline
            B Offline
            Bob Stanneveld
            wrote on last edited by
            #12

            Hello, As some other user already suggested, you should use virtual base classes (if you want to share among the different types). See Here[^] for more information on virtual inheritance. Another way to go (IMHO the better way) is to encapsulate some details of your base classes using private inheritance instead of public. Also you need to override some other functions to resolve the ambiguities:

            struct WFIOInfo
            { HANDLE m_hFile;
            DWORD m_dwBytes;
            };

            class WinFileInInterface
            {
            public:
            virtual BOOL Open(LPCTSTR lpszFileName);
            virtual BOOL DoReadFile(LPVOID lpBuffer, DWORD nNumberOfBytesToRead);
            };

            class WinFileOutInterface
            {
            public:
            virtual BOOL Open(LPCTSTR lpszFileName);
            virtual BOOL DoWriteFile(LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite);
            };

            class CWinFileIn : private WFIOInfo, public WinFileInInterface
            {
            public:
            virtual BOOL Open(LPCTSTR lpszFileName)
            {return TRUE;}
            virtual BOOL DoReadFile(LPVOID lpBuffer, DWORD nNumberOfBytesToRead)
            {return ::ReadFile(m_hFile, lpBuffer, nNumberOfBytesToRead, &m_dwBytes, NULL);}
            };

            class CWinFileOut : private WFIOInfo, WinFileOutInterface
            {
            public:
            virtual BOOL Open(LPCTSTR lpszFileName) {return TRUE;}
            virtual BOOL DoWriteFile(LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite)
            {return ::WriteFile(m_hFile, lpBuffer, nNumberOfBytesToWrite, &m_dwBytes, NULL);}
            };

            class CWinFileInOut : private: WFIOInfo,
            public: WinFileInInterface,
            public: WinFileOutInterface
            {
            public:
            BOOL Open(LPCTSTR lpszFileName)
            { return TRUE; }
            };

            Using the private inheritance, you make the class only visible and accessible to the class that derives from it. Classes which are derived from that class, do not know about the previous privatly inherited classes. This way, you can have multiple names inside different classes. Hope this helps :-D Behind every great black man...             ... is the police. - Conspiracy brother Blog[^]

            1 Reply Last reply
            0
            • G GDavy

              an interface should be purely abstract so put a =0 behind function definitions. class WinFileInInterface { public: virtual BOOL Open(LPCTSTR lpszFileName) = 0; virtual BOOL DoReadFile(LPVOID lpBuffer, DWORD nNumberOfBytesToRead) = 0; }; class WinFileOutInterface { public: virtual BOOL Open(LPCTSTR lpszFileName) = 0; virtual BOOL DoWriteFile(LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite) = 0; };

              N Offline
              N Offline
              nm_114
              wrote on last edited by
              #13

              When I tried that I got the following errors:

              Compiling...
              winiotest.cpp
              C:\C++\Projects\[Tests]\winiotest\winiotest.cpp(29) : error C2259: 'CWinFileInOut' : cannot instantiate abstract class due to following members:
              c:\c++\projects\[tests]\winiotest\cwinfileio.h(109) : see declaration of 'CWinFileInOut'
              C:\C++\Projects\[Tests]\winiotest\winiotest.cpp(29) : warning C4259: 'int __thiscall WinFileInInterface::DoReadFile(void *,unsigned long)' : pure virtual function was not defined
              c:\c++\projects\[tests]\winiotest\cwinfileio.h(73) : see declaration of 'DoReadFile'
              C:\C++\Projects\[Tests]\winiotest\winiotest.cpp(29) : warning C4259: 'int __thiscall WinFileOutInterface::DoWriteFile(const void *,unsigned long)' : pure virtual function was not defined
              c:\c++\projects\[tests]\winiotest\cwinfileio.h(80) : see declaration of 'DoWriteFile'
              C:\C++\Projects\[Tests]\winiotest\winiotest.cpp(29) : error C2259: 'CWinFileInOut' : cannot instantiate abstract class due to following members:
              c:\c++\projects\[tests]\winiotest\cwinfileio.h(109) : see declaration of 'CWinFileInOut'
              C:\C++\Projects\[Tests]\winiotest\winiotest.cpp(29) : warning C4259: 'int __thiscall WinFileInInterface::DoReadFile(void *,unsigned long)' : pure virtual function was not defined
              c:\c++\projects\[tests]\winiotest\cwinfileio.h(73) : see declaration of 'DoReadFile'
              C:\C++\Projects\[Tests]\winiotest\winiotest.cpp(29) : warning C4259: 'int __thiscall WinFileOutInterface::DoWriteFile(const void *,unsigned long)' : pure virtual function was not defined
              c:\c++\projects\[tests]\winiotest\cwinfileio.h(80) : see declaration of 'DoWriteFile'

              1 Reply Last reply
              0
              • C Christian Graus

                struct WFIOInfo { ... } class WinFileInInterface // Note - NOT derived from WFIOInfo, defines an interface for what CWinFIleIn has that WFIOInfo does not { virtual void myMethod; //etc } class WinFileOutInterface { virtual void myMethod; //etc } class CWinFileIn : WFIOInfo, WinFileInInterface { } class CWinFileOut : WFIOInfo, WinFileOutInterface { } class CWinFileInOut : WFINInfo, WinFileInInterface, WinFileOutInterface { } So, CWinFileInOut is not derived from either derived class, but from all three base classes that combine to make the class you're after. Christian Graus - Microsoft MVP - C++

                N Offline
                N Offline
                nm_114
                wrote on last edited by
                #14

                After looking at this closer it turns out I don't understand how this works. If CWinFileInOut derives just from interfaces, doesn't that mean I have copy the implementations of the interfaces of CWinFileIn and CWinFileOut to CWinFileInOut, which makes inheritance pointless :confused:

                C 1 Reply Last reply
                0
                • N nm_114

                  After looking at this closer it turns out I don't understand how this works. If CWinFileInOut derives just from interfaces, doesn't that mean I have copy the implementations of the interfaces of CWinFileIn and CWinFileOut to CWinFileInOut, which makes inheritance pointless :confused:

                  C Offline
                  C Offline
                  Christian Graus
                  wrote on last edited by
                  #15

                  There's no such thing as interfaces in C++. These are base classes which define the interfaces. Yes, perhaps this is not what you want, but a virtual base class will have the same problem. Christian Graus - Microsoft MVP - C++

                  N 1 Reply Last reply
                  0
                  • C Christian Graus

                    There's no such thing as interfaces in C++. These are base classes which define the interfaces. Yes, perhaps this is not what you want, but a virtual base class will have the same problem. Christian Graus - Microsoft MVP - C++

                    N Offline
                    N Offline
                    nm_114
                    wrote on last edited by
                    #16

                    "base classes which define the interfaces" is what i meant when saying interfaces, sorry for confusing the terms. so, um, sorry if i'm being dense but is what i was originally asking even possible? in the example with the virtual base classes, the derived classes CWinFileIn and CWinFileOut have to implement the virtual functions, and the same virtual functions have to be implemented again in CWinFileInOut, which kinda defeats the purpose of inheritance.

                    C 1 Reply Last reply
                    0
                    • N nm_114

                      "base classes which define the interfaces" is what i meant when saying interfaces, sorry for confusing the terms. so, um, sorry if i'm being dense but is what i was originally asking even possible? in the example with the virtual base classes, the derived classes CWinFileIn and CWinFileOut have to implement the virtual functions, and the same virtual functions have to be implemented again in CWinFileInOut, which kinda defeats the purpose of inheritance.

                      C Offline
                      C Offline
                      Christian Graus
                      wrote on last edited by
                      #17

                      Yes, that's definately the problem, I doubt what you want to do is possible. You can make a class that is all three class types, but you need to copy a bit of code between the classes to do it. Christian Graus - Microsoft MVP - C++

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups