A Better Class Design

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Bryan Parkoff

    A Better Class Design

    I have created three classes according to my own design. First class
    is called CMain. It is the Top Class. Second class and third class are
    called CMemory and CMPU. They are the sub-classes.
    Two sub-classes have the relationship to communicate back and forth
    through this pointer. The pointer is responsible inside Top class for
    allocating and deallocating two sub-classes.
    CMemory class is responsible to allocate and deallocate memory while
    CMPU class does not. I tell the pointer to copy m_pMemoryRegist er's
    memory address from CMemory class to CMPU class. It is done once during
    the initialization.
    After the initialization is done, the functionality can perform all
    the tasks inside CMPU class rather than depending on CMemory class so it
    can gain a big impact of this performance.
    I understand that some C programmers prefer to leave all variables
    and functions in the global. In fact, it won't be efficiency because all
    variables and functions have fixed memory that they are stored in data
    segment. They can't perform the tasks into 80x86's L1 Cache.
    It is best to store both variables and functions inside class because
    they can be very efficiency. They are stored in stack segment. They can
    be able to perform the tasks into 80x86's L1 Cache.
    Please read my simple code below. Please state your opinion to see
    if my programming code for class is a good design. I appreciate that you
    can provide what you think is best.


    class CMain
    {
    public:
    CMain();
    virtual ~CMain();

    CMemory* Get_Memory();
    CMPU* Get_MPU();

    void Initialize(void );
    void Terminate(void) ;
    void Run(void);

    private:
    CMemory* m_pMemory;
    CMPU6502* m_pMPU;
    };

    CMain::CMain()
    {
    m_pMemory = new CMemory(this);
    m_pMPU = new CMPU(this);
    }

    CMain::~CMain()
    {
    delete m_pMemory;
    delete m_pMPU;
    }

    CMemory* CMain::Get_Memo ry()
    {
    return m_pMemory;
    }

    CMPU* CMain::Get_MPU( )
    {
    return m_pMPU;
    }

    void CMain::Initiali ze(void)
    {

    }

    void CMain::Terminat e(void)
    {

    }

    void CMain::Run(void )
    {
    m_pMPU->Run();
    }

    class CMemory
    {
    public:
    CMemory();
    virtual ~CMemory();

    CMemory(CMain* pMain);

    void Initialize(void );
    void Terminate(void) ;
    void Run(void);

    unsigned char Get_MemoryRegis ter(void);

    private:
    CMain* m_pMain;
    unsigned char m_pMemoryRegist er;
    };

    CMemory::CMemor y()
    {
    Initialize();
    }

    CMemory::~CMemo ry()
    {
    Terminate();
    }

    CMemory::CMemor y(CMain* pMain)
    {
    m_pMain = pMain;
    Initialize();
    }

    void CMemory::Initia lize(void)
    {
    m_pMemoryRegist er = new unsigned char [0x10000];
    memset(&m_pMemo ryRegister[0], 0x00, 0x10000);
    }

    void CMemory::Termin ate(void)
    {
    delete [] m_pMemoryRegist er;
    }

    void CMemory::Run(vo id)
    {

    }

    PU_BYTE CMemory::Get_Me moryRegister(vo id)
    {
    return m_pMemoryRegist er;
    }


    class CMPU
    {
    public:
    CMPU();
    virtual ~CMPU();

    CMPU(CMain* pMain);

    void Initialize(void );
    void Terminate(void) ;
    void Run(void);

    private:
    CMain* m_pMain;
    unsigned char m_pMemoryRegist er;
    };

    CMPU::CMPU()
    {
    Initialize();
    }

    CMPU::~CMPU()
    {
    Terminate();
    }

    CMPU::CMPU(CMai n* pMain)
    {
    m_pMain = pMain;
    Initialize();
    }

    void CMPU::Initializ e(void)
    {
    m_pMemoryRegist er = m_pMain->Get_Memory()->Get_MemoryRegi ster();
    }

    void CMPU6502::Termi nate(void)
    {

    }

    void CMPU6502::Run(v oid)
    {

    }

    int main(void)
    {
    CMain Main;
    Main.Run();

    return 0;
    }

    --
    Bryan Parkoff


  • Steven T. Hatton

    #2
    Re: A Better Class Design

    Bryan Parkoff wrote:
    [color=blue]
    > I have created three classes according to my own design. First class
    > is called CMain. It is the Top Class. Second class and third class are
    > called CMemory and CMPU. They are the sub-classes.
    > Two sub-classes have the relationship to communicate back and forth
    > through this pointer. The pointer is responsible inside Top class for
    > allocating and deallocating two sub-classes.
    > CMemory class is responsible to allocate and deallocate memory while
    > CMPU class does not. I tell the pointer to copy m_pMemoryRegist er's
    > memory address from CMemory class to CMPU class. It is done once during
    > the initialization.
    > After the initialization is done, the functionality can perform all
    > the tasks inside CMPU class rather than depending on CMemory class so it
    > can gain a big impact of this performance.
    > I understand that some C programmers prefer to leave all variables
    > and functions in the global. In fact, it won't be efficiency because all
    > variables and functions have fixed memory that they are stored in data
    > segment. They can't perform the tasks into 80x86's L1 Cache.
    > It is best to store both variables and functions inside class because
    > they can be very efficiency. They are stored in stack segment. They can
    > be able to perform the tasks into 80x86's L1 Cache.
    > Please read my simple code below. Please state your opinion to see
    > if my programming code for class is a good design. I appreciate that you
    > can provide what you think is best.[/color]

    I find the code interesting, but I'm not an expert in C++. I don't fully
    understand what you are suggesting. Are you trying some kind of ipc, or
    running your own memory manager?

    --
    p->m == (*p).m == p[0].m

    Modernize your infrastructure with SUSE Linux Enterprise servers, cloud technology for IaaS, and SUSE's software-defined...

    Mozilla is the not-for-profit behind the lightning fast Firefox browser. We put people over profit to give everyone more power online.

    Comment

    • Steven T. Hatton

      #3
      Re: A Better Class Design

      Bryan Parkoff wrote:
      [color=blue]
      > I have created three classes according to my own design. First class
      > is called CMain. It is the Top Class. Second class and third class are
      > called CMemory and CMPU. They are the sub-classes.
      > Two sub-classes have the relationship to communicate back and forth
      > through this pointer. The pointer is responsible inside Top class for
      > allocating and deallocating two sub-classes.
      > CMemory class is responsible to allocate and deallocate memory while
      > CMPU class does not. I tell the pointer to copy m_pMemoryRegist er's
      > memory address from CMemory class to CMPU class. It is done once during
      > the initialization.
      > After the initialization is done, the functionality can perform all
      > the tasks inside CMPU class rather than depending on CMemory class so it
      > can gain a big impact of this performance.
      > I understand that some C programmers prefer to leave all variables
      > and functions in the global. In fact, it won't be efficiency because all
      > variables and functions have fixed memory that they are stored in data
      > segment. They can't perform the tasks into 80x86's L1 Cache.
      > It is best to store both variables and functions inside class because
      > they can be very efficiency. They are stored in stack segment. They can
      > be able to perform the tasks into 80x86's L1 Cache.
      > Please read my simple code below. Please state your opinion to see
      > if my programming code for class is a good design. I appreciate that you
      > can provide what you think is best.[/color]

      I find the code interesting, but I'm not an expert in C++. I don't fully
      understand what you are suggesting. Are you trying some kind of ipc, or
      running your own memory manager?

      --
      p->m == (*p).m == p[0].m

      Modernize your infrastructure with SUSE Linux Enterprise servers, cloud technology for IaaS, and SUSE's software-defined...

      Mozilla is the not-for-profit behind the lightning fast Firefox browser. We put people over profit to give everyone more power online.

      Comment

      • Pete Vidler

        #4
        Re: A Better Class Design

        Bryan Parkoff wrote:
        [snip confusing text][color=blue]
        > Please read my simple code below. Please state your opinion to see
        > if my programming code for class is a good design. I appreciate that you
        > can provide what you think is best.[/color]

        I've listed a few problems with the code inline below. Note that I
        couldn't make much sense of your main text, so I might be missing the point.
        [color=blue]
        > class CMain
        > {
        > public:
        > CMain();
        > virtual ~CMain();[/color]

        A virtual destructor usually indicates that this is meant to be a base
        class. If you follow the advice of Scott Meyers ("More Effective C++"
        item 33) then base classes (and all non-leaf classes) should be abstract.

        Even if you don't follow that advice, I see no reason for a virtual
        destructor unless you have specific extension scenarios in mind (which
        you might, but I didn't see them).
        [color=blue]
        > CMemory* Get_Memory();
        > CMPU* Get_MPU();[/color]

        If you /must/ return raw pointers (and I don't recommend it), then at
        least provide const versions of your get methods (with const return
        values, obviously). Then your code will still be usable within other
        const methods.
        [color=blue]
        > void Initialize(void );
        > void Terminate(void) ;
        > void Run(void);
        >
        > private:
        > CMemory* m_pMemory;
        > CMPU6502* m_pMPU;[/color]

        There are many problems with raw pointers. You might consider smart
        pointers, such as from the boost or loki libraries.
        [color=blue]
        > };
        >
        > CMain::CMain()
        > {
        > m_pMemory = new CMemory(this);
        > m_pMPU = new CMPU(this);
        > }[/color]

        What happens if one of those throws an exception? In general, you should
        keep one resource to a class to avoid these issues (or use smart pointers).
        [color=blue]
        > CMain::~CMain()
        > {
        > delete m_pMemory;
        > delete m_pMPU;
        > }[/color]

        Where is the copy constructor and copy assignment operator? If you don't
        have them the compiler will generate them for you. The compiler
        generated versions will not work properly for this class... they will
        simply copy the pointer and not the data it points to. Then you call
        'delete' on those pointers twice (from each destructor)...

        Even if CMain is not meant to be copied, you should make those two
        methods private (or declare them, but don't implement them). This stops
        people from making mistakes with your code.

        [snip rest of code]

        Maybe if you include a description of exactly what you were trying to
        do, rather than a description of the classes you have?

        -- Pete

        Comment

        • Pete Vidler

          #5
          Re: A Better Class Design

          Bryan Parkoff wrote:
          [snip confusing text][color=blue]
          > Please read my simple code below. Please state your opinion to see
          > if my programming code for class is a good design. I appreciate that you
          > can provide what you think is best.[/color]

          I've listed a few problems with the code inline below. Note that I
          couldn't make much sense of your main text, so I might be missing the point.
          [color=blue]
          > class CMain
          > {
          > public:
          > CMain();
          > virtual ~CMain();[/color]

          A virtual destructor usually indicates that this is meant to be a base
          class. If you follow the advice of Scott Meyers ("More Effective C++"
          item 33) then base classes (and all non-leaf classes) should be abstract.

          Even if you don't follow that advice, I see no reason for a virtual
          destructor unless you have specific extension scenarios in mind (which
          you might, but I didn't see them).
          [color=blue]
          > CMemory* Get_Memory();
          > CMPU* Get_MPU();[/color]

          If you /must/ return raw pointers (and I don't recommend it), then at
          least provide const versions of your get methods (with const return
          values, obviously). Then your code will still be usable within other
          const methods.
          [color=blue]
          > void Initialize(void );
          > void Terminate(void) ;
          > void Run(void);
          >
          > private:
          > CMemory* m_pMemory;
          > CMPU6502* m_pMPU;[/color]

          There are many problems with raw pointers. You might consider smart
          pointers, such as from the boost or loki libraries.
          [color=blue]
          > };
          >
          > CMain::CMain()
          > {
          > m_pMemory = new CMemory(this);
          > m_pMPU = new CMPU(this);
          > }[/color]

          What happens if one of those throws an exception? In general, you should
          keep one resource to a class to avoid these issues (or use smart pointers).
          [color=blue]
          > CMain::~CMain()
          > {
          > delete m_pMemory;
          > delete m_pMPU;
          > }[/color]

          Where is the copy constructor and copy assignment operator? If you don't
          have them the compiler will generate them for you. The compiler
          generated versions will not work properly for this class... they will
          simply copy the pointer and not the data it points to. Then you call
          'delete' on those pointers twice (from each destructor)...

          Even if CMain is not meant to be copied, you should make those two
          methods private (or declare them, but don't implement them). This stops
          people from making mistakes with your code.

          [snip rest of code]

          Maybe if you include a description of exactly what you were trying to
          do, rather than a description of the classes you have?

          -- Pete

          Comment

          • Siemel Naran

            #6
            Re: A Better Class Design

            "Bryan Parkoff" <bryan.nospam.p arkoff@nospam.c om> wrote in message
            news:BlGdc.1141 2$jR6.3556@fe2. texas.rr.com...
            [color=blue]
            > I have created three classes according to my own design. First class
            > is called CMain. It is the Top Class. Second class and third class are
            > called CMemory and CMPU. They are the sub-classes.
            > Two sub-classes have the relationship to communicate back and forth
            > through this pointer. The pointer is responsible inside Top class for
            > allocating and deallocating two sub-classes.[/color]

            Then the copy constructor and operator= of the sub-classes should probably
            be private and not implemented to prevent users from copying one CMemory or
            CMPU object to another. Alternatively choose the design in the next
            paragraph.

            On the other hand, if you clone one of these objects, which CMain does the
            cloned object point to? This is an important question, because when the
            CMain goes out of scope it destroys the CMemory and CMPU objects it owns, so
            if two CMemory objects can point to the same CMain, the CMain has to have an
            array of pointers to CMemory objects (not just one pointer as in your class
            below).
            [color=blue]
            > CMemory class is responsible to allocate and deallocate memory while
            > CMPU class does not. I tell the pointer to copy m_pMemoryRegist er's
            > memory address from CMemory class to CMPU class. It is done once during
            > the initialization.[/color]

            Why does CMPU not own the CMemory class? I think I see the reason: 2 CMPU
            objects may share the same memory, right?
            [color=blue]
            > After the initialization is done, the functionality can perform all
            > the tasks inside CMPU class rather than depending on CMemory class so it
            > can gain a big impact of this performance.
            > I understand that some C programmers prefer to leave all variables
            > and functions in the global. In fact, it won't be efficiency because all
            > variables and functions have fixed memory that they are stored in data
            > segment. They can't perform the tasks into 80x86's L1 Cache.
            > It is best to store both variables and functions inside class because
            > they can be very efficiency. They are stored in stack segment. They can
            > be able to perform the tasks into 80x86's L1 Cache.
            > Please read my simple code below. Please state your opinion to see
            > if my programming code for class is a good design. I appreciate that you
            > can provide what you think is best.
            >
            >
            > class CMain
            > {
            > public:
            > CMain();
            > virtual ~CMain();
            >
            > CMemory* Get_Memory();
            > CMPU* Get_MPU();
            >
            > void Initialize(void );
            > void Terminate(void) ;
            > void Run(void);
            >
            > private:
            > CMemory* m_pMemory;
            > CMPU6502* m_pMPU;
            > };[/color]

            Since CMain owns the CMemory and CMPU objects, consider using a smart
            pointer like std::auto_ptr<C Memory>. You get exception safety in the
            constructor, as noted below. Note that if your CMain.h header file does not
            include CMemory.h and CMPU.h, you must declare the destructor in the header
            file as above, and define it in the cpp file with an empty function body.
            You should consider declaring the copy constructor and operator= of CMain
            private and not implemented.

            In all your classes, Initialize and Terminate are helper functions called
            from the constructor and destructor, so make them private. Alternatively,
            maybe you could eliminate these functions altogether.

            In your code you use both CMPU and CMPU6502. Is one of these the base
            class, and the other a derived class?
            [color=blue]
            > CMain::CMain()
            > {
            > m_pMemory = new CMemory(this);
            > m_pMPU = new CMPU(this);
            > }[/color]

            If the new CMPU(this) fails to find memory it throws an exception
            std::bad_alloc. The m_pMemory won't be destroyed because the destrructor
            CMain::~CMain() cannot be called for incompletely initialized objects, which
            are objects that have not fully finished the constructor. Thus you have a
            potential memory leak. So the easiest fix is to use smart pointers like
            std::auto_ptr<C Memory> as the member variable m_pMemory. You could also use
            new (nothrow), try catch-blocks, etc.
            [color=blue]
            > CMain::~CMain()
            > {
            > delete m_pMemory;
            > delete m_pMPU;
            > }
            >
            > CMemory* CMain::Get_Memo ry()
            > {
            > return m_pMemory;
            > }[/color]

            If Get_Memory always returns valid memory, consider returning a reference
            instead of a pointer. Same for the next function.
            [color=blue]
            > CMPU* CMain::Get_MPU( )
            > {
            > return m_pMPU;
            > }
            >
            > void CMain::Initiali ze(void)
            > {
            >
            > }
            >
            > void CMain::Terminat e(void)
            > {
            >
            > }
            >
            > void CMain::Run(void )
            > {
            > m_pMPU->Run();
            > }
            >
            > class CMemory
            > {
            > public:
            > CMemory();
            > virtual ~CMemory();
            >
            > CMemory(CMain* pMain);
            >
            > void Initialize(void );
            > void Terminate(void) ;
            > void Run(void);
            >
            > unsigned char Get_MemoryRegis ter(void);
            >
            > private:
            > CMain* m_pMain;
            > unsigned char m_pMemoryRegist er;
            > };[/color]

            What does it mean to copy a CMemory object through the copy constructor or
            operator=?
            [color=blue]
            > CMemory::CMemor y()
            > {
            > Initialize();
            > }[/color]

            Variable m_pMain is not initialized, not even to NULL. It points to junk
            data. Anyway, do it make sense to have a default constructor? Same
            question for CMPU.
            [color=blue]
            > CMemory::~CMemo ry()
            > {
            > Terminate();
            > }
            >
            > CMemory::CMemor y(CMain* pMain)
            > {
            > m_pMain = pMain;
            > Initialize();
            > }
            >
            > void CMemory::Initia lize(void)
            > {
            > m_pMemoryRegist er = new unsigned char [0x10000];
            > memset(&m_pMemo ryRegister[0], 0x00, 0x10000);
            > }
            >
            > void CMemory::Termin ate(void)
            > {
            > delete [] m_pMemoryRegist er;
            > }
            >
            > void CMemory::Run(vo id)
            > {
            >
            > }
            >
            > PU_BYTE CMemory::Get_Me moryRegister(vo id)
            > {
            > return m_pMemoryRegist er;
            > }
            >
            >
            > class CMPU
            > {
            > public:
            > CMPU();
            > virtual ~CMPU();
            >
            > CMPU(CMain* pMain);
            >
            > void Initialize(void );
            > void Terminate(void) ;
            > void Run(void);
            >
            > private:
            > CMain* m_pMain;
            > unsigned char m_pMemoryRegist er;
            > };
            >
            > CMPU::CMPU()
            > {
            > Initialize();
            > }
            >
            > CMPU::~CMPU()
            > {
            > Terminate();
            > }
            >
            > CMPU::CMPU(CMai n* pMain)
            > {
            > m_pMain = pMain;
            > Initialize();
            > }
            >
            > void CMPU::Initializ e(void)
            > {
            > m_pMemoryRegist er = m_pMain->Get_Memory()->Get_MemoryRegi ster();
            > }[/color]

            Above means CMPU.cpp has to include CMemory.h in order to use the
            Get_MemoryRegis ter function. Consider changing the constructor to
            CMPU(unsigned char *), or adding the function Get_MemoryRegis ter to class
            CMain too.
            [color=blue]
            > void CMPU6502::Termi nate(void)
            > {
            >
            > }
            >
            > void CMPU6502::Run(v oid)
            > {
            >
            > }
            >
            > int main(void)
            > {
            > CMain Main;
            > Main.Run();
            >
            > return 0;
            > }
            >
            > --
            > Bryan Parkoff
            >
            >[/color]


            Comment

            • Siemel Naran

              #7
              Re: A Better Class Design

              "Bryan Parkoff" <bryan.nospam.p arkoff@nospam.c om> wrote in message
              news:BlGdc.1141 2$jR6.3556@fe2. texas.rr.com...
              [color=blue]
              > I have created three classes according to my own design. First class
              > is called CMain. It is the Top Class. Second class and third class are
              > called CMemory and CMPU. They are the sub-classes.
              > Two sub-classes have the relationship to communicate back and forth
              > through this pointer. The pointer is responsible inside Top class for
              > allocating and deallocating two sub-classes.[/color]

              Then the copy constructor and operator= of the sub-classes should probably
              be private and not implemented to prevent users from copying one CMemory or
              CMPU object to another. Alternatively choose the design in the next
              paragraph.

              On the other hand, if you clone one of these objects, which CMain does the
              cloned object point to? This is an important question, because when the
              CMain goes out of scope it destroys the CMemory and CMPU objects it owns, so
              if two CMemory objects can point to the same CMain, the CMain has to have an
              array of pointers to CMemory objects (not just one pointer as in your class
              below).
              [color=blue]
              > CMemory class is responsible to allocate and deallocate memory while
              > CMPU class does not. I tell the pointer to copy m_pMemoryRegist er's
              > memory address from CMemory class to CMPU class. It is done once during
              > the initialization.[/color]

              Why does CMPU not own the CMemory class? I think I see the reason: 2 CMPU
              objects may share the same memory, right?
              [color=blue]
              > After the initialization is done, the functionality can perform all
              > the tasks inside CMPU class rather than depending on CMemory class so it
              > can gain a big impact of this performance.
              > I understand that some C programmers prefer to leave all variables
              > and functions in the global. In fact, it won't be efficiency because all
              > variables and functions have fixed memory that they are stored in data
              > segment. They can't perform the tasks into 80x86's L1 Cache.
              > It is best to store both variables and functions inside class because
              > they can be very efficiency. They are stored in stack segment. They can
              > be able to perform the tasks into 80x86's L1 Cache.
              > Please read my simple code below. Please state your opinion to see
              > if my programming code for class is a good design. I appreciate that you
              > can provide what you think is best.
              >
              >
              > class CMain
              > {
              > public:
              > CMain();
              > virtual ~CMain();
              >
              > CMemory* Get_Memory();
              > CMPU* Get_MPU();
              >
              > void Initialize(void );
              > void Terminate(void) ;
              > void Run(void);
              >
              > private:
              > CMemory* m_pMemory;
              > CMPU6502* m_pMPU;
              > };[/color]

              Since CMain owns the CMemory and CMPU objects, consider using a smart
              pointer like std::auto_ptr<C Memory>. You get exception safety in the
              constructor, as noted below. Note that if your CMain.h header file does not
              include CMemory.h and CMPU.h, you must declare the destructor in the header
              file as above, and define it in the cpp file with an empty function body.
              You should consider declaring the copy constructor and operator= of CMain
              private and not implemented.

              In all your classes, Initialize and Terminate are helper functions called
              from the constructor and destructor, so make them private. Alternatively,
              maybe you could eliminate these functions altogether.

              In your code you use both CMPU and CMPU6502. Is one of these the base
              class, and the other a derived class?
              [color=blue]
              > CMain::CMain()
              > {
              > m_pMemory = new CMemory(this);
              > m_pMPU = new CMPU(this);
              > }[/color]

              If the new CMPU(this) fails to find memory it throws an exception
              std::bad_alloc. The m_pMemory won't be destroyed because the destrructor
              CMain::~CMain() cannot be called for incompletely initialized objects, which
              are objects that have not fully finished the constructor. Thus you have a
              potential memory leak. So the easiest fix is to use smart pointers like
              std::auto_ptr<C Memory> as the member variable m_pMemory. You could also use
              new (nothrow), try catch-blocks, etc.
              [color=blue]
              > CMain::~CMain()
              > {
              > delete m_pMemory;
              > delete m_pMPU;
              > }
              >
              > CMemory* CMain::Get_Memo ry()
              > {
              > return m_pMemory;
              > }[/color]

              If Get_Memory always returns valid memory, consider returning a reference
              instead of a pointer. Same for the next function.
              [color=blue]
              > CMPU* CMain::Get_MPU( )
              > {
              > return m_pMPU;
              > }
              >
              > void CMain::Initiali ze(void)
              > {
              >
              > }
              >
              > void CMain::Terminat e(void)
              > {
              >
              > }
              >
              > void CMain::Run(void )
              > {
              > m_pMPU->Run();
              > }
              >
              > class CMemory
              > {
              > public:
              > CMemory();
              > virtual ~CMemory();
              >
              > CMemory(CMain* pMain);
              >
              > void Initialize(void );
              > void Terminate(void) ;
              > void Run(void);
              >
              > unsigned char Get_MemoryRegis ter(void);
              >
              > private:
              > CMain* m_pMain;
              > unsigned char m_pMemoryRegist er;
              > };[/color]

              What does it mean to copy a CMemory object through the copy constructor or
              operator=?
              [color=blue]
              > CMemory::CMemor y()
              > {
              > Initialize();
              > }[/color]

              Variable m_pMain is not initialized, not even to NULL. It points to junk
              data. Anyway, do it make sense to have a default constructor? Same
              question for CMPU.
              [color=blue]
              > CMemory::~CMemo ry()
              > {
              > Terminate();
              > }
              >
              > CMemory::CMemor y(CMain* pMain)
              > {
              > m_pMain = pMain;
              > Initialize();
              > }
              >
              > void CMemory::Initia lize(void)
              > {
              > m_pMemoryRegist er = new unsigned char [0x10000];
              > memset(&m_pMemo ryRegister[0], 0x00, 0x10000);
              > }
              >
              > void CMemory::Termin ate(void)
              > {
              > delete [] m_pMemoryRegist er;
              > }
              >
              > void CMemory::Run(vo id)
              > {
              >
              > }
              >
              > PU_BYTE CMemory::Get_Me moryRegister(vo id)
              > {
              > return m_pMemoryRegist er;
              > }
              >
              >
              > class CMPU
              > {
              > public:
              > CMPU();
              > virtual ~CMPU();
              >
              > CMPU(CMain* pMain);
              >
              > void Initialize(void );
              > void Terminate(void) ;
              > void Run(void);
              >
              > private:
              > CMain* m_pMain;
              > unsigned char m_pMemoryRegist er;
              > };
              >
              > CMPU::CMPU()
              > {
              > Initialize();
              > }
              >
              > CMPU::~CMPU()
              > {
              > Terminate();
              > }
              >
              > CMPU::CMPU(CMai n* pMain)
              > {
              > m_pMain = pMain;
              > Initialize();
              > }
              >
              > void CMPU::Initializ e(void)
              > {
              > m_pMemoryRegist er = m_pMain->Get_Memory()->Get_MemoryRegi ster();
              > }[/color]

              Above means CMPU.cpp has to include CMemory.h in order to use the
              Get_MemoryRegis ter function. Consider changing the constructor to
              CMPU(unsigned char *), or adding the function Get_MemoryRegis ter to class
              CMain too.
              [color=blue]
              > void CMPU6502::Termi nate(void)
              > {
              >
              > }
              >
              > void CMPU6502::Run(v oid)
              > {
              >
              > }
              >
              > int main(void)
              > {
              > CMain Main;
              > Main.Run();
              >
              > return 0;
              > }
              >
              > --
              > Bryan Parkoff
              >
              >[/color]


              Comment

              • Bryan Parkoff

                #8
                Re: A Better Class Design

                Siemel,

                Thank you for the answer. I believe that it is almost exact what you
                mean. It is my typo for CMPU and CMPU6502 however I choose to use CMPU as
                the primary name instead of CMPU6502. CMemory class and CMPU class are
                really sub-classes. They are not derived from base class. It is just base
                class alone.
                I don't add copy constructor and operator = to each Top class and
                sub-class because I have no intention to make copies of one object because I
                want to initialize only one object at this time. You recommend that copy
                constructor and operator= should be private. I agree with you. You
                recommend that it should not be provided by compiler, but only user's
                writing code.
                Can you please provide your sample code of copy constructor and
                operator= that are never used under private?

                I want CMPU and CMemory sub-classes to be private except constructor and
                deconstructor functions (they are not allowed to be private.) Only CMain
                class can access CMPU sub-class and CMemory sub-class through pointer
                relationship. I can only be able to write "CMain Main; Main.Run();" under
                "int main (void)". "Main.Run() " will point and access CMPU::Run() and
                CMemory::Run() that they are always private.
                The problem is that CMain class can't access private functions through
                pointer relationship.

                I am not talking about Memory Manager like CMemory sub-class. I hate to
                write "allocate memory" and "deallocate memory" in each sub-classes. I
                decide to put "allocate memory" and "deallocate memory" in CMemory sub-class
                while CMPU sub-class does not have "allocate memory" and "deallocate
                memory".
                After memory is being allocated in CMemory sub-class, four bytes of
                memory address has to be copied from CMemory sub-class to CMPU sub-class.
                It would be very slow to load and store data into array through pointer
                relationship from CMPU sub-class to CMemory sub-class, but it would be
                easier to access four bytes of memory address indirectly inside CMPU
                sub-class.
                After deallocating memory in CMemory sub-class, four bytes of address
                memory in CMPU sub-class will be set to NULL automatically rather than
                deallocating memory second time that can lead to memory leak.
                Can you please provide the information about smart pointer? Where can I
                find website or book that it can help me to learn how to handle smart
                pointer?
                Try to think five to ten objects. Five to ten objects are sub-classes
                that they point to CMain class. They are like printer, modem, disk,
                keyboard, display, and etc. They are all private. If there is no way that
                all sub-classes are private, it would be a bad idea to place sub-classes
                inside CMain class like nested class. What do you think?
                You may be correct that "virtual" is not necessary because I have no
                intention to derive a new class from base class.
                Please advise.

                --
                Bryan Parkoff
                "Siemel Naran" <SiemelNaran@RE MOVE.att.net> wrote in message
                news:OuYdc.5381 $K_.166482@bgtn sc05-news.ops.worldn et.att.net...[color=blue]
                > "Bryan Parkoff" <bryan.nospam.p arkoff@nospam.c om> wrote in message
                > news:BlGdc.1141 2$jR6.3556@fe2. texas.rr.com...
                >[color=green]
                > > I have created three classes according to my own design. First class
                > > is called CMain. It is the Top Class. Second class and third class are
                > > called CMemory and CMPU. They are the sub-classes.
                > > Two sub-classes have the relationship to communicate back and forth
                > > through this pointer. The pointer is responsible inside Top class for
                > > allocating and deallocating two sub-classes.[/color]
                >
                > Then the copy constructor and operator= of the sub-classes should probably
                > be private and not implemented to prevent users from copying one CMemory[/color]
                or[color=blue]
                > CMPU object to another. Alternatively choose the design in the next
                > paragraph.
                >
                > On the other hand, if you clone one of these objects, which CMain does the
                > cloned object point to? This is an important question, because when the
                > CMain goes out of scope it destroys the CMemory and CMPU objects it owns,[/color]
                so[color=blue]
                > if two CMemory objects can point to the same CMain, the CMain has to have[/color]
                an[color=blue]
                > array of pointers to CMemory objects (not just one pointer as in your[/color]
                class[color=blue]
                > below).
                >[color=green]
                > > CMemory class is responsible to allocate and deallocate memory while
                > > CMPU class does not. I tell the pointer to copy m_pMemoryRegist er's
                > > memory address from CMemory class to CMPU class. It is done once during
                > > the initialization.[/color]
                >
                > Why does CMPU not own the CMemory class? I think I see the reason: 2 CMPU
                > objects may share the same memory, right?
                >[color=green]
                > > After the initialization is done, the functionality can perform all
                > > the tasks inside CMPU class rather than depending on CMemory class so it
                > > can gain a big impact of this performance.
                > > I understand that some C programmers prefer to leave all variables
                > > and functions in the global. In fact, it won't be efficiency because[/color][/color]
                all[color=blue][color=green]
                > > variables and functions have fixed memory that they are stored in data
                > > segment. They can't perform the tasks into 80x86's L1 Cache.
                > > It is best to store both variables and functions inside class because
                > > they can be very efficiency. They are stored in stack segment. They[/color][/color]
                can[color=blue][color=green]
                > > be able to perform the tasks into 80x86's L1 Cache.
                > > Please read my simple code below. Please state your opinion to see
                > > if my programming code for class is a good design. I appreciate that[/color][/color]
                you[color=blue][color=green]
                > > can provide what you think is best.
                > >
                > >
                > > class CMain
                > > {
                > > public:
                > > CMain();
                > > virtual ~CMain();
                > >
                > > CMemory* Get_Memory();
                > > CMPU* Get_MPU();
                > >
                > > void Initialize(void );
                > > void Terminate(void) ;
                > > void Run(void);
                > >
                > > private:
                > > CMemory* m_pMemory;
                > > CMPU6502* m_pMPU;
                > > };[/color]
                >
                > Since CMain owns the CMemory and CMPU objects, consider using a smart
                > pointer like std::auto_ptr<C Memory>. You get exception safety in the
                > constructor, as noted below. Note that if your CMain.h header file does[/color]
                not[color=blue]
                > include CMemory.h and CMPU.h, you must declare the destructor in the[/color]
                header[color=blue]
                > file as above, and define it in the cpp file with an empty function body.
                > You should consider declaring the copy constructor and operator= of CMain
                > private and not implemented.
                >
                > In all your classes, Initialize and Terminate are helper functions called
                > from the constructor and destructor, so make them private. Alternatively,
                > maybe you could eliminate these functions altogether.
                >
                > In your code you use both CMPU and CMPU6502. Is one of these the base
                > class, and the other a derived class?
                >[color=green]
                > > CMain::CMain()
                > > {
                > > m_pMemory = new CMemory(this);
                > > m_pMPU = new CMPU(this);
                > > }[/color]
                >
                > If the new CMPU(this) fails to find memory it throws an exception
                > std::bad_alloc. The m_pMemory won't be destroyed because the destrructor
                > CMain::~CMain() cannot be called for incompletely initialized objects,[/color]
                which[color=blue]
                > are objects that have not fully finished the constructor. Thus you have a
                > potential memory leak. So the easiest fix is to use smart pointers like
                > std::auto_ptr<C Memory> as the member variable m_pMemory. You could also[/color]
                use[color=blue]
                > new (nothrow), try catch-blocks, etc.
                >[color=green]
                > > CMain::~CMain()
                > > {
                > > delete m_pMemory;
                > > delete m_pMPU;
                > > }
                > >
                > > CMemory* CMain::Get_Memo ry()
                > > {
                > > return m_pMemory;
                > > }[/color]
                >
                > If Get_Memory always returns valid memory, consider returning a reference
                > instead of a pointer. Same for the next function.
                >[color=green]
                > > CMPU* CMain::Get_MPU( )
                > > {
                > > return m_pMPU;
                > > }
                > >
                > > void CMain::Initiali ze(void)
                > > {
                > >
                > > }
                > >
                > > void CMain::Terminat e(void)
                > > {
                > >
                > > }
                > >
                > > void CMain::Run(void )
                > > {
                > > m_pMPU->Run();
                > > }
                > >
                > > class CMemory
                > > {
                > > public:
                > > CMemory();
                > > virtual ~CMemory();
                > >
                > > CMemory(CMain* pMain);
                > >
                > > void Initialize(void );
                > > void Terminate(void) ;
                > > void Run(void);
                > >
                > > unsigned char Get_MemoryRegis ter(void);
                > >
                > > private:
                > > CMain* m_pMain;
                > > unsigned char m_pMemoryRegist er;
                > > };[/color]
                >
                > What does it mean to copy a CMemory object through the copy constructor or
                > operator=?
                >[color=green]
                > > CMemory::CMemor y()
                > > {
                > > Initialize();
                > > }[/color]
                >
                > Variable m_pMain is not initialized, not even to NULL. It points to junk
                > data. Anyway, do it make sense to have a default constructor? Same
                > question for CMPU.
                >[color=green]
                > > CMemory::~CMemo ry()
                > > {
                > > Terminate();
                > > }
                > >
                > > CMemory::CMemor y(CMain* pMain)
                > > {
                > > m_pMain = pMain;
                > > Initialize();
                > > }
                > >
                > > void CMemory::Initia lize(void)
                > > {
                > > m_pMemoryRegist er = new unsigned char [0x10000];
                > > memset(&m_pMemo ryRegister[0], 0x00, 0x10000);
                > > }
                > >
                > > void CMemory::Termin ate(void)
                > > {
                > > delete [] m_pMemoryRegist er;
                > > }
                > >
                > > void CMemory::Run(vo id)
                > > {
                > >
                > > }
                > >
                > > PU_BYTE CMemory::Get_Me moryRegister(vo id)
                > > {
                > > return m_pMemoryRegist er;
                > > }
                > >
                > >
                > > class CMPU
                > > {
                > > public:
                > > CMPU();
                > > virtual ~CMPU();
                > >
                > > CMPU(CMain* pMain);
                > >
                > > void Initialize(void );
                > > void Terminate(void) ;
                > > void Run(void);
                > >
                > > private:
                > > CMain* m_pMain;
                > > unsigned char m_pMemoryRegist er;
                > > };
                > >
                > > CMPU::CMPU()
                > > {
                > > Initialize();
                > > }
                > >
                > > CMPU::~CMPU()
                > > {
                > > Terminate();
                > > }
                > >
                > > CMPU::CMPU(CMai n* pMain)
                > > {
                > > m_pMain = pMain;
                > > Initialize();
                > > }
                > >
                > > void CMPU::Initializ e(void)
                > > {
                > > m_pMemoryRegist er = m_pMain->Get_Memory()->Get_MemoryRegi ster();
                > > }[/color]
                >
                > Above means CMPU.cpp has to include CMemory.h in order to use the
                > Get_MemoryRegis ter function. Consider changing the constructor to
                > CMPU(unsigned char *), or adding the function Get_MemoryRegis ter to class
                > CMain too.
                >[color=green]
                > > void CMPU6502::Termi nate(void)
                > > {
                > >
                > > }
                > >
                > > void CMPU6502::Run(v oid)
                > > {
                > >
                > > }
                > >
                > > int main(void)
                > > {
                > > CMain Main;
                > > Main.Run();
                > >
                > > return 0;
                > > }
                > >
                > > --
                > > Bryan Parkoff
                > >
                > >[/color]
                >
                >[/color]


                Comment

                • Bryan Parkoff

                  #9
                  Re: A Better Class Design

                  Siemel,

                  Thank you for the answer. I believe that it is almost exact what you
                  mean. It is my typo for CMPU and CMPU6502 however I choose to use CMPU as
                  the primary name instead of CMPU6502. CMemory class and CMPU class are
                  really sub-classes. They are not derived from base class. It is just base
                  class alone.
                  I don't add copy constructor and operator = to each Top class and
                  sub-class because I have no intention to make copies of one object because I
                  want to initialize only one object at this time. You recommend that copy
                  constructor and operator= should be private. I agree with you. You
                  recommend that it should not be provided by compiler, but only user's
                  writing code.
                  Can you please provide your sample code of copy constructor and
                  operator= that are never used under private?

                  I want CMPU and CMemory sub-classes to be private except constructor and
                  deconstructor functions (they are not allowed to be private.) Only CMain
                  class can access CMPU sub-class and CMemory sub-class through pointer
                  relationship. I can only be able to write "CMain Main; Main.Run();" under
                  "int main (void)". "Main.Run() " will point and access CMPU::Run() and
                  CMemory::Run() that they are always private.
                  The problem is that CMain class can't access private functions through
                  pointer relationship.

                  I am not talking about Memory Manager like CMemory sub-class. I hate to
                  write "allocate memory" and "deallocate memory" in each sub-classes. I
                  decide to put "allocate memory" and "deallocate memory" in CMemory sub-class
                  while CMPU sub-class does not have "allocate memory" and "deallocate
                  memory".
                  After memory is being allocated in CMemory sub-class, four bytes of
                  memory address has to be copied from CMemory sub-class to CMPU sub-class.
                  It would be very slow to load and store data into array through pointer
                  relationship from CMPU sub-class to CMemory sub-class, but it would be
                  easier to access four bytes of memory address indirectly inside CMPU
                  sub-class.
                  After deallocating memory in CMemory sub-class, four bytes of address
                  memory in CMPU sub-class will be set to NULL automatically rather than
                  deallocating memory second time that can lead to memory leak.
                  Can you please provide the information about smart pointer? Where can I
                  find website or book that it can help me to learn how to handle smart
                  pointer?
                  Try to think five to ten objects. Five to ten objects are sub-classes
                  that they point to CMain class. They are like printer, modem, disk,
                  keyboard, display, and etc. They are all private. If there is no way that
                  all sub-classes are private, it would be a bad idea to place sub-classes
                  inside CMain class like nested class. What do you think?
                  You may be correct that "virtual" is not necessary because I have no
                  intention to derive a new class from base class.
                  Please advise.

                  --
                  Bryan Parkoff
                  "Siemel Naran" <SiemelNaran@RE MOVE.att.net> wrote in message
                  news:OuYdc.5381 $K_.166482@bgtn sc05-news.ops.worldn et.att.net...[color=blue]
                  > "Bryan Parkoff" <bryan.nospam.p arkoff@nospam.c om> wrote in message
                  > news:BlGdc.1141 2$jR6.3556@fe2. texas.rr.com...
                  >[color=green]
                  > > I have created three classes according to my own design. First class
                  > > is called CMain. It is the Top Class. Second class and third class are
                  > > called CMemory and CMPU. They are the sub-classes.
                  > > Two sub-classes have the relationship to communicate back and forth
                  > > through this pointer. The pointer is responsible inside Top class for
                  > > allocating and deallocating two sub-classes.[/color]
                  >
                  > Then the copy constructor and operator= of the sub-classes should probably
                  > be private and not implemented to prevent users from copying one CMemory[/color]
                  or[color=blue]
                  > CMPU object to another. Alternatively choose the design in the next
                  > paragraph.
                  >
                  > On the other hand, if you clone one of these objects, which CMain does the
                  > cloned object point to? This is an important question, because when the
                  > CMain goes out of scope it destroys the CMemory and CMPU objects it owns,[/color]
                  so[color=blue]
                  > if two CMemory objects can point to the same CMain, the CMain has to have[/color]
                  an[color=blue]
                  > array of pointers to CMemory objects (not just one pointer as in your[/color]
                  class[color=blue]
                  > below).
                  >[color=green]
                  > > CMemory class is responsible to allocate and deallocate memory while
                  > > CMPU class does not. I tell the pointer to copy m_pMemoryRegist er's
                  > > memory address from CMemory class to CMPU class. It is done once during
                  > > the initialization.[/color]
                  >
                  > Why does CMPU not own the CMemory class? I think I see the reason: 2 CMPU
                  > objects may share the same memory, right?
                  >[color=green]
                  > > After the initialization is done, the functionality can perform all
                  > > the tasks inside CMPU class rather than depending on CMemory class so it
                  > > can gain a big impact of this performance.
                  > > I understand that some C programmers prefer to leave all variables
                  > > and functions in the global. In fact, it won't be efficiency because[/color][/color]
                  all[color=blue][color=green]
                  > > variables and functions have fixed memory that they are stored in data
                  > > segment. They can't perform the tasks into 80x86's L1 Cache.
                  > > It is best to store both variables and functions inside class because
                  > > they can be very efficiency. They are stored in stack segment. They[/color][/color]
                  can[color=blue][color=green]
                  > > be able to perform the tasks into 80x86's L1 Cache.
                  > > Please read my simple code below. Please state your opinion to see
                  > > if my programming code for class is a good design. I appreciate that[/color][/color]
                  you[color=blue][color=green]
                  > > can provide what you think is best.
                  > >
                  > >
                  > > class CMain
                  > > {
                  > > public:
                  > > CMain();
                  > > virtual ~CMain();
                  > >
                  > > CMemory* Get_Memory();
                  > > CMPU* Get_MPU();
                  > >
                  > > void Initialize(void );
                  > > void Terminate(void) ;
                  > > void Run(void);
                  > >
                  > > private:
                  > > CMemory* m_pMemory;
                  > > CMPU6502* m_pMPU;
                  > > };[/color]
                  >
                  > Since CMain owns the CMemory and CMPU objects, consider using a smart
                  > pointer like std::auto_ptr<C Memory>. You get exception safety in the
                  > constructor, as noted below. Note that if your CMain.h header file does[/color]
                  not[color=blue]
                  > include CMemory.h and CMPU.h, you must declare the destructor in the[/color]
                  header[color=blue]
                  > file as above, and define it in the cpp file with an empty function body.
                  > You should consider declaring the copy constructor and operator= of CMain
                  > private and not implemented.
                  >
                  > In all your classes, Initialize and Terminate are helper functions called
                  > from the constructor and destructor, so make them private. Alternatively,
                  > maybe you could eliminate these functions altogether.
                  >
                  > In your code you use both CMPU and CMPU6502. Is one of these the base
                  > class, and the other a derived class?
                  >[color=green]
                  > > CMain::CMain()
                  > > {
                  > > m_pMemory = new CMemory(this);
                  > > m_pMPU = new CMPU(this);
                  > > }[/color]
                  >
                  > If the new CMPU(this) fails to find memory it throws an exception
                  > std::bad_alloc. The m_pMemory won't be destroyed because the destrructor
                  > CMain::~CMain() cannot be called for incompletely initialized objects,[/color]
                  which[color=blue]
                  > are objects that have not fully finished the constructor. Thus you have a
                  > potential memory leak. So the easiest fix is to use smart pointers like
                  > std::auto_ptr<C Memory> as the member variable m_pMemory. You could also[/color]
                  use[color=blue]
                  > new (nothrow), try catch-blocks, etc.
                  >[color=green]
                  > > CMain::~CMain()
                  > > {
                  > > delete m_pMemory;
                  > > delete m_pMPU;
                  > > }
                  > >
                  > > CMemory* CMain::Get_Memo ry()
                  > > {
                  > > return m_pMemory;
                  > > }[/color]
                  >
                  > If Get_Memory always returns valid memory, consider returning a reference
                  > instead of a pointer. Same for the next function.
                  >[color=green]
                  > > CMPU* CMain::Get_MPU( )
                  > > {
                  > > return m_pMPU;
                  > > }
                  > >
                  > > void CMain::Initiali ze(void)
                  > > {
                  > >
                  > > }
                  > >
                  > > void CMain::Terminat e(void)
                  > > {
                  > >
                  > > }
                  > >
                  > > void CMain::Run(void )
                  > > {
                  > > m_pMPU->Run();
                  > > }
                  > >
                  > > class CMemory
                  > > {
                  > > public:
                  > > CMemory();
                  > > virtual ~CMemory();
                  > >
                  > > CMemory(CMain* pMain);
                  > >
                  > > void Initialize(void );
                  > > void Terminate(void) ;
                  > > void Run(void);
                  > >
                  > > unsigned char Get_MemoryRegis ter(void);
                  > >
                  > > private:
                  > > CMain* m_pMain;
                  > > unsigned char m_pMemoryRegist er;
                  > > };[/color]
                  >
                  > What does it mean to copy a CMemory object through the copy constructor or
                  > operator=?
                  >[color=green]
                  > > CMemory::CMemor y()
                  > > {
                  > > Initialize();
                  > > }[/color]
                  >
                  > Variable m_pMain is not initialized, not even to NULL. It points to junk
                  > data. Anyway, do it make sense to have a default constructor? Same
                  > question for CMPU.
                  >[color=green]
                  > > CMemory::~CMemo ry()
                  > > {
                  > > Terminate();
                  > > }
                  > >
                  > > CMemory::CMemor y(CMain* pMain)
                  > > {
                  > > m_pMain = pMain;
                  > > Initialize();
                  > > }
                  > >
                  > > void CMemory::Initia lize(void)
                  > > {
                  > > m_pMemoryRegist er = new unsigned char [0x10000];
                  > > memset(&m_pMemo ryRegister[0], 0x00, 0x10000);
                  > > }
                  > >
                  > > void CMemory::Termin ate(void)
                  > > {
                  > > delete [] m_pMemoryRegist er;
                  > > }
                  > >
                  > > void CMemory::Run(vo id)
                  > > {
                  > >
                  > > }
                  > >
                  > > PU_BYTE CMemory::Get_Me moryRegister(vo id)
                  > > {
                  > > return m_pMemoryRegist er;
                  > > }
                  > >
                  > >
                  > > class CMPU
                  > > {
                  > > public:
                  > > CMPU();
                  > > virtual ~CMPU();
                  > >
                  > > CMPU(CMain* pMain);
                  > >
                  > > void Initialize(void );
                  > > void Terminate(void) ;
                  > > void Run(void);
                  > >
                  > > private:
                  > > CMain* m_pMain;
                  > > unsigned char m_pMemoryRegist er;
                  > > };
                  > >
                  > > CMPU::CMPU()
                  > > {
                  > > Initialize();
                  > > }
                  > >
                  > > CMPU::~CMPU()
                  > > {
                  > > Terminate();
                  > > }
                  > >
                  > > CMPU::CMPU(CMai n* pMain)
                  > > {
                  > > m_pMain = pMain;
                  > > Initialize();
                  > > }
                  > >
                  > > void CMPU::Initializ e(void)
                  > > {
                  > > m_pMemoryRegist er = m_pMain->Get_Memory()->Get_MemoryRegi ster();
                  > > }[/color]
                  >
                  > Above means CMPU.cpp has to include CMemory.h in order to use the
                  > Get_MemoryRegis ter function. Consider changing the constructor to
                  > CMPU(unsigned char *), or adding the function Get_MemoryRegis ter to class
                  > CMain too.
                  >[color=green]
                  > > void CMPU6502::Termi nate(void)
                  > > {
                  > >
                  > > }
                  > >
                  > > void CMPU6502::Run(v oid)
                  > > {
                  > >
                  > > }
                  > >
                  > > int main(void)
                  > > {
                  > > CMain Main;
                  > > Main.Run();
                  > >
                  > > return 0;
                  > > }
                  > >
                  > > --
                  > > Bryan Parkoff
                  > >
                  > >[/color]
                  >
                  >[/color]


                  Comment

                  • Steven T. Hatton

                    #10
                    Re: A Better Class Design

                    Bryan Parkoff wrote:
                    [color=blue]
                    > Siemel,
                    >
                    > Thank you for the answer. I believe that it is almost exact what you
                    > mean. It is my typo for CMPU and CMPU6502 however I choose to use CMPU as
                    > the primary name instead of CMPU6502. CMemory class and CMPU class are
                    > really sub-classes. They are not derived from base class. It is just
                    > base class alone.[/color]

                    Perhaps this should be obvious to any qualified C++ programmer, but it's not
                    obvious to me. What are you actually trying to achieve? When I first
                    looked at your code, I realized that I was not about to compile it and try
                    it on my system. I had visions of some kind of recursive consumption of
                    memory without any protection from the OS. But that may just be
                    paranoia. :-).

                    I believe your goal is to somehow keep your resources in the CPU cache, and
                    micromanage where your program puts data, or something similar. Is this
                    correct?
                    --
                    STH
                    Hatton's Law: "There is only One inviolable Law"
                    KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
                    Mozilla: http://www.mozilla.org

                    Comment

                    • Steven T. Hatton

                      #11
                      Re: A Better Class Design

                      Bryan Parkoff wrote:
                      [color=blue]
                      > Siemel,
                      >
                      > Thank you for the answer. I believe that it is almost exact what you
                      > mean. It is my typo for CMPU and CMPU6502 however I choose to use CMPU as
                      > the primary name instead of CMPU6502. CMemory class and CMPU class are
                      > really sub-classes. They are not derived from base class. It is just
                      > base class alone.[/color]

                      Perhaps this should be obvious to any qualified C++ programmer, but it's not
                      obvious to me. What are you actually trying to achieve? When I first
                      looked at your code, I realized that I was not about to compile it and try
                      it on my system. I had visions of some kind of recursive consumption of
                      memory without any protection from the OS. But that may just be
                      paranoia. :-).

                      I believe your goal is to somehow keep your resources in the CPU cache, and
                      micromanage where your program puts data, or something similar. Is this
                      correct?
                      --
                      STH
                      Hatton's Law: "There is only One inviolable Law"
                      KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
                      Mozilla: http://www.mozilla.org

                      Comment

                      • Siemel Naran

                        #12
                        Re: A Better Class Design

                        "Bryan Parkoff" <bryan.nospam.p arkoff@nospam.c om> wrote in message
                        news:uy4ec.1378 2$jR6.9087@fe2. texas.rr.com...
                        [color=blue]
                        > Thank you for the answer. I believe that it is almost exact what you
                        > mean. It is my typo for CMPU and CMPU6502 however I choose to use CMPU as
                        > the primary name instead of CMPU6502. CMemory class and CMPU class are
                        > really sub-classes. They are not derived from base class. It is just[/color]
                        base[color=blue]
                        > class alone.[/color]

                        BTW, the term sub-class means derived class. As I gathered from your
                        original post and this one, I think you mean contained class?
                        [color=blue]
                        > I don't add copy constructor and operator = to each Top class and
                        > sub-class because I have no intention to make copies of one object because[/color]
                        I[color=blue]
                        > want to initialize only one object at this time. You recommend that copy
                        > constructor and operator= should be private. I agree with you. You
                        > recommend that it should not be provided by compiler, but only user's
                        > writing code.
                        > Can you please provide your sample code of copy constructor and
                        > operator= that are never used under private?[/color]

                        For example,

                        class CMPU
                        {
                        public:
                        ...
                        private:
                        CMPU(const CMPU&); // not implemented
                        CMPU& operator=(const CMPU&); // not implemented
                        };

                        If anyone tries to call these functions they get an error that function is
                        private and not accessible. If you want to get more fancy

                        class notcopyable
                        {
                        public:
                        notcopyable() { }
                        private:
                        notcopyable(con st notcopyable&); // not implemented
                        notcopyable& operator=(const notcopyable&); // not implemented
                        };

                        and derived your class CMPU from notcopyable

                        class CMPU : private notcopyable { ... };

                        I believe boost has a similar class.

                        [color=blue]
                        > I want CMPU and CMemory sub-classes to be private except constructor[/color]
                        and[color=blue]
                        > deconstructor functions (they are not allowed to be private.) Only CMain
                        > class can access CMPU sub-class and CMemory sub-class through pointer
                        > relationship. I can only be able to write "CMain Main; Main.Run();" under
                        > "int main (void)". "Main.Run() " will point and access CMPU::Run() and
                        > CMemory::Run() that they are always private.
                        > The problem is that CMain class can't access private functions through
                        > pointer relationship.[/color]

                        You could use friends. On the other hand, if outside users don't even know
                        about the CMPU and CMemory objects inside CMain, and they can't get
                        references to the CMPU etc objects inside CMain, what does it matter if the
                        functions are public? In fact you could declare class CMPU inside
                        CMain.cpp, so that users who include CMain.h don't even see these classes at
                        all.
                        [color=blue]
                        > I am not talking about Memory Manager like CMemory sub-class. I hate[/color]
                        to[color=blue]
                        > write "allocate memory" and "deallocate memory" in each sub-classes. I
                        > decide to put "allocate memory" and "deallocate memory" in CMemory[/color]
                        sub-class[color=blue]
                        > while CMPU sub-class does not have "allocate memory" and "deallocate
                        > memory".[/color]

                        Is one CMemory object shared by several CMPU objects? If no, then it makes
                        sense to me to put everything into one class. You could for instance CMPU
                        contain an instance of a CMemory.
                        [color=blue]
                        > Can you please provide the information about smart pointer? Where can[/color]
                        I[color=blue]
                        > find website or book that it can help me to learn how to handle smart
                        > pointer?[/color]

                        Search the web for "smart pointer", "auto_ptr", "shared_ptr ", "counted_pt r".


                        Comment

                        • Bryan Parkoff

                          #13
                          Re: A Better Class Design

                          Siemel,
                          [color=blue]
                          > Is one CMemory object shared by several CMPU objects? If no, then it[/color]
                          makes[color=blue]
                          > sense to me to put everything into one class. You could for instance CMPU
                          > contain an instance of a CMemory.[/color]
                          Yes, two or more CMPU objects point to the same memory address that
                          CMemory already allocated.
                          [color=blue][color=green]
                          > > Can you please provide the information about smart pointer? Where[/color][/color]
                          can[color=blue]
                          > I[color=green]
                          > > find website or book that it can help me to learn how to handle smart
                          > > pointer?[/color][/color]

                          I will research to see smart pointer.

                          Do you understand that printer class, modem class, display class,
                          keyboard class, and other classes are the only base class that they are
                          linked to CMain class. They are all private except CMain. Do you suggest
                          that they should be inside CMain class such as nested class (It is bad
                          idea.) Or...Should I use "friends" inside CMain class that it can perform
                          the private functions from printer class, modem class, etc. It makes sense
                          that friends is useful. Why do you think that printer class, modem class,
                          etc should be derived from CMain? I understand that sub-class term refer
                          derived class however variables and functions should notRC]inherited from
                          CMain class. Please advise.

                          Bryan Parkoff


                          Comment

                          • Siemel Naran

                            #14
                            Re: A Better Class Design

                            "Bryan Parkoff" <bryan.nospam.p arkoff@nospam.c om> wrote in message
                            news:SIiec.1845 5
                            [color=blue]
                            > Do you understand that printer class, modem class, display class,
                            > keyboard class, and other classes are the only base class that they are
                            > linked to CMain class. They are all private except CMain. Do you suggest
                            > that they should be inside CMain class such as nested class (It is bad
                            > idea.) Or...Should I use "friends" inside CMain class that it can perform
                            > the private functions from printer class, modem class, etc. It makes[/color]
                            sense[color=blue]
                            > that friends is useful. Why do you think that printer class, modem class,
                            > etc should be derived from CMain? I understand that sub-class term refer
                            > derived class however variables and functions should notRC]inherited from
                            > CMain class. Please advise.[/color]

                            Use either nested classes or non-nested classes as you see fit. Neither
                            design is inherently better than the other, but you can't forward declare
                            nested classes, and they automatically inherit all typedefs/classes of the
                            parent class which may or may not be a good thing. Sorry if you
                            misunderstood, I don't think printer etc should derive from CMain, but that
                            CMain should contain an instance of each of these objects as private data
                            members.


                            Comment

                            Working...