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. use the member pointer via a Get function and allocate memory outside, not clear why in this way

use the member pointer via a Get function and allocate memory outside, not clear why in this way

Scheduled Pinned Locked Moved C / C++ / MFC
questionperformancetutorial
3 Posts 3 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.
  • G Offline
    G Offline
    George Nistor
    wrote on last edited by
    #1

    hi guys probably already discussed but I did not find the explenation: in the above code: My question is why I have to use reference to the pointer when returning from mGetPt? If this pointer whould have been used inside the function, and for example used in constructor to allocate memory if I have an Get function like CInner* mGetPt(void) I am able to use the pointer as I want. but in the above example it is required to return a reference. (this is the return value, is not a function param; OK I know in case of function params I have to use reference to pinter) Please someone clarify me why?

    class CInner
    {
    public:
    int mx;

    CInner()
    {
    	mx=1;
    }
    

    };

    class CTest
    {
    private:
    CInner *pt;

    public:
    CTest()
    {
    pt= NULL;
    }

    CInner\*& mGetPt(void)
    {
    	return pt;
    }
    

    };

    int _tmain(int argc, _TCHAR* argv[])
    {
    CTest *obj= new CTest();

    obj->mGetPt() = new CInner();
    
    cout<<obj->mGetPt()->mx;
    
    cin.get();
    return 0;
    

    }

    N A 2 Replies Last reply
    0
    • G George Nistor

      hi guys probably already discussed but I did not find the explenation: in the above code: My question is why I have to use reference to the pointer when returning from mGetPt? If this pointer whould have been used inside the function, and for example used in constructor to allocate memory if I have an Get function like CInner* mGetPt(void) I am able to use the pointer as I want. but in the above example it is required to return a reference. (this is the return value, is not a function param; OK I know in case of function params I have to use reference to pinter) Please someone clarify me why?

      class CInner
      {
      public:
      int mx;

      CInner()
      {
      	mx=1;
      }
      

      };

      class CTest
      {
      private:
      CInner *pt;

      public:
      CTest()
      {
      pt= NULL;
      }

      CInner\*& mGetPt(void)
      {
      	return pt;
      }
      

      };

      int _tmain(int argc, _TCHAR* argv[])
      {
      CTest *obj= new CTest();

      obj->mGetPt() = new CInner();
      
      cout<<obj->mGetPt()->mx;
      
      cin.get();
      return 0;
      

      }

      N Offline
      N Offline
      Niklas L
      wrote on last edited by
      #2

      You need to return a reference to the pointer if you want an outsider to be able to change the value of that pointer. It looks like an ugly attempt to make dependency injection. A setter/getter would IMO be clearer. Who's responsible for deallocating the instance? The contract isn't clear at all. If trying something like that, a massive comment block describing responsibilities would be a minimum.

      home

      1 Reply Last reply
      0
      • G George Nistor

        hi guys probably already discussed but I did not find the explenation: in the above code: My question is why I have to use reference to the pointer when returning from mGetPt? If this pointer whould have been used inside the function, and for example used in constructor to allocate memory if I have an Get function like CInner* mGetPt(void) I am able to use the pointer as I want. but in the above example it is required to return a reference. (this is the return value, is not a function param; OK I know in case of function params I have to use reference to pinter) Please someone clarify me why?

        class CInner
        {
        public:
        int mx;

        CInner()
        {
        	mx=1;
        }
        

        };

        class CTest
        {
        private:
        CInner *pt;

        public:
        CTest()
        {
        pt= NULL;
        }

        CInner\*& mGetPt(void)
        {
        	return pt;
        }
        

        };

        int _tmain(int argc, _TCHAR* argv[])
        {
        CTest *obj= new CTest();

        obj->mGetPt() = new CInner();
        
        cout<<obj->mGetPt()->mx;
        
        cin.get();
        return 0;
        

        }

        A Offline
        A Offline
        Andrew Brock
        wrote on last edited by
        #3

        Firstly, I agree with Niklas, this is terrible style and structure. A class should be responsible for allocating and deallocating all its memory. To answer your question, returning a pointer allows you to modify the data that is pointed to (in your case this is NULL, so it would result in an access violation). Returning a reference allows you to modify the value of the original variable returned (think of reference as "another name for the variable X") So, in order to modify the value of the variable pt rather than the data it points to, you can either return a reference to the variable, or a pointer to the variable itself. You are returning the reference, to return a pointer you would use it like:

        //class CTest
        CInner** mGetPt(void) {
        return &pt;
        }

        //_tmain()
        *obj->mGetPt() = new CInner();

        Having said that, this is still bad style, and you would be much better off with something like:

        class CInner {
        public:
        CInner() : mx(1) { } //This is an initialiser list, and is equivalent to "mx = 1". This is quicker and cleaner than using "mx = 1"
        int GetMX() { return mx; }
        void SetMX(int nNewMx) { mx = nNewMx; } //This allows you to validate the value getting set, and is good style even if you don't need to validate it

        private:
        	int mx; //It is good style to have variables as private, or protected, then have a get/set function which can validate the value
        

        };

        For CTest you have 2 choices, you can either allocate pt = new CInner in the constructor or when it is needed.

        //Preallocate solution
        class CTest {
        public:
        CTest() : pt(new CInner) { } //Allocate in the constructor
        ~CTest() {
        if (pt != NULL) {
        delete pt; //Don't forget to delete the memory
        }
        }
        CInner *mGetPt() { return pt; } //Don't return by reference, it is bad style

        private:
        	CInner \*pt;
        

        };

        //Allocate on demand solution
        class CTest {
        public:
        CTest() : pt(NULL) { } //Set to NULL
        ~CTest() {
        if (pt != NULL) {
        delete pt; //Don't forget to delete the memory
        }
        }
        CInner *mGetPt() { //Don't return by reference, it is bad style
        if (pt == NULL) {
        pt = new CInner;
        }
        return pt;
        }

        private:
        	CInner \*pt;
        

        };

        You can then use it like:

        int _tmain(int argc, TCHAR *argv[]) {
        CTest *obj = new CTest();
        cout << obj->mGetPt()->GetMX();
        cin.get();
        return 0;
        }

        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