Classes and Pointer Issues

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • kief12
    New Member
    • Jul 2007
    • 13

    Classes and Pointer Issues

    I am having trouble accessing and setting data from inside classes.
    if have a program set up similar to this example
    Code:
    ---Desk.h----
    #include "Pen.h"
    class Desk
    {
    private:
      Pen myPen;
    public:
      Desk();
      void setPen(Pen*);
      Pen* getPen();
    }
    ---Desk.cpp-----
    Desk::Desk(){}
    Pen* Desk::getPen()
    {
      return &myPen;
    }
    void setPen(Pen* p)
    {
      myPen = p
    }
    Then the pen class looks like
    Code:
    ---Pen.h---
    #include <string>
    class Pen
    {
     private:
      string penName;
     public:
      Pen();
      string getPenName();
      void setPenName(string);
    }
    --Pen.cpp---
    include "Pen.cpp"
    Pen::Pen(){
     penName = "Bic";
    }
    string Pen::getPenName()
    {
     return penName()
    }
    void Pen::setPenName(string s)
    {
     penName = s
    }
    from the main function i have
    Code:
     Desk myDesk;
     cout << myDesk.getPen()->getPenName();
    This code works but if i send *myDesk to another class and try to use it like
    Code:
    --Main.cpp---
    ...
    myOtherClass.setDesk(&myDesk);
    ...
    ---OtherClass.h---
    ...
    Desk* myDesk;
    ...
    ---OtherClass.cpp---
    ...
    void randomFunction(){
     string s = myDesk->getPen()->getPenName()
    ...
    string s = myDesk->getPen()->getPenName() line crashes the program

    how can i do this correctly?

    Thank you,
  • emaghero
    New Member
    • Oct 2006
    • 85

    #2
    Originally posted by kief12
    I am having trouble accessing and setting data from inside classes.
    if have a program set up similar to this example
    Code:
    ---Desk.h----
    #include "Pen.h"
    class Desk
    {
    private:
      Pen myPen;
    public:
      Desk();
      void setPen(Pen*);
      Pen* getPen();
    }
    ---Desk.cpp-----
    Desk::Desk(){}
    Pen* Desk::getPen()
    {
      return &myPen;
    }
    void setPen(Pen* p)
    {
      myPen = p
    }
    Then the pen class looks like
    Code:
    ---Pen.h---
    #include <string>
    class Pen
    {
     private:
      string penName;
     public:
      Pen();
      string getPenName();
      void setPenName(string);
    }
    --Pen.cpp---
    include "Pen.cpp"
    Pen::Pen(){
     penName = "Bic";
    }
    string Pen::getPenName()
    {
     return penName()
    }
    void Pen::setPenName(string s)
    {
     penName = s
    }
    from the main function i have
    Code:
     Desk myDesk;
     cout << myDesk.getPen()->getPenName();
    This code works but if i send *myDesk to another class and try to use it like
    Code:
    --Main.cpp---
    ...
    myOtherClass.setDesk(&myDesk);
    ...
    ---OtherClass.h---
    ...
    Desk* myDesk;
    ...
    ---OtherClass.cpp---
    ...
    void randomFunction(){
     string s = myDesk->getPen()->getPenName()
    ...
    string s = myDesk->getPen()->getPenName() line crashes the program

    how can i do this correctly?

    Thank you,
    Declare the desk class as a friend of the myOtherClass class

    That way you can access members of the desk class

    Comment

    • kief12
      New Member
      • Jul 2007
      • 13

      #3
      Originally posted by emaghero
      Declare the desk class as a friend of the myOtherClass class

      That way you can access members of the desk class
      Sorry i don't understand how that would help.

      i could do
      Code:
      myOtherClass.getPen();
      but that would not be referring to the same pen would it?

      I want to keep the same instance of Desk and have myOtherClass get the original desks values

      Comment

      • Darryl
        New Member
        • May 2007
        • 86

        #4
        Code:
        string Pen::getPenName()
        
        {
        
         return penName();\\ <-ERROR
         
        // return penName; < -correct
        
        }
        remove the parenthesis after penName()

        On another note, your code to returnPen() returns a pointer to the actual Pen which make the fact that it's private pointless, because now anyone can get the Pen and change it. Instead you should return a const Pen&

        Comment

        • kief12
          New Member
          • Jul 2007
          • 13

          #5
          Sorry i set up code that had the same problem as mine but this is not the actual code i didn't mean to put in the () and they are not there in my real code. i am changing the code to use But that still leaves me in the same place.

          Comment

          • kief12
            New Member
            • Jul 2007
            • 13

            #6
            I think the problem maybe how i am passing the Desk to myOtherClass
            from main.cpp
            i do
            Code:
             myOtherClass.setDesk(&myDesk);
            and myOtherClass has
            Code:
            void myOtherClass::setDesk(Desk* d)
            {
              myDesk = d;
            }
            i changed getPen to return a Pen not a pointer to one but this line gives me and exception not caught line in myOtherClass
            Code:
            if (myDesk != NULL)
            {
             Pen myPen = Desk->getPen();
            }
            Thank You,

            Comment

            • weaknessforcats
              Recognized Expert Expert
              • Mar 2007
              • 9214

              #7
              Try to avoid this style of coding:

              Originally posted by kief12
              string s = myDesk->getPen()->getPenName()
              This is the famous spaghetti code. If the methods of those indirect classes chnage, the code in main() breaks. That means the user code breaks. If you have a lot of users, you won't be able to redesign those indirect classes because the users will block you. Your application dies at this point.

              Also, if myDesk is 0 you crash.
              Also, if MyDesk is not 0 but getPen() returns 0, you crash

              You need to check pointers for null before using them.

              I suggest you makee your Desk class protective:

              [code=cpp]
              string Desk::getPenNam e()
              {
              return this->myPen.getPenNa me();
              }
              [/code]

              Then in main() all you do is:

              [code=cpp]
              string s = myDesk->getPenName() ;
              [/code]

              which is much cleaner and the user only needs to know about the Desk class.

              Interface design is a big deal and takes practice.

              Comment

              • kief12
                New Member
                • Jul 2007
                • 13

                #8
                Doing that seems like there will be a lot of repetition. Like if i also add a Coffee Mug class i would need to place it methods into Desk to. Is there a better way to go about that?

                Comment

                • weaknessforcats
                  Recognized Expert Expert
                  • Mar 2007
                  • 9214

                  #9
                  It's not about repetition. It's about interface design. And that means encapsulation.

                  If the user is going to be using Desk objects, then only Desk member functions should be called. Otherwise, your user has to learn every class the Desk uses in addition to learning the Desk. Worse, if you need to re-design any of those classes, your user won't like it. For example:

                  Version 1.0
                  [code=cpp]
                  string Desk::getPenNam e()
                  {
                  return this->myPen.getPenNa me();
                  }
                  [/code]

                  Version 2.0
                  [code=cpp]
                  string Desk::getPenNam e()
                  {
                  return this->myPen->getPenName() ;
                  }
                  [/code]

                  Between Version 1.0 and Version 2.0 it was decided to have a Pen* in Desk rather than an Pen. That was to allow the Pen to change values independently from the Desk. That is, the relationship between Desk and Pen was changed from HAS-A to ASSOCIATES-A.

                  The only change required was to Desk::getPenNam e(). No user code was impacted. Otherwise, the user woul have to change all the code using the Pen.

                  Comment

                  • kief12
                    New Member
                    • Jul 2007
                    • 13

                    #10
                    I am still having the same problem i can run myDesk.getPenNa me() but from the other file myDesk->getPenName() doesn't work

                    Comment

                    Working...