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;
}