Compare these two codes

Does anyone possibly explain for me which code is the better one?
These all work fine.

Style 1:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  // Bug Buster

#include <iostream>

using namespace std;

class CAT
{
public:
	CAT (int age) { itsAge = age; }
	~CAT() {}
	int getAge() const { return itsAge; }
private:
	int itsAge;
};

CAT & MakeCat(int age);

int main()
{
	int age = 7;
	CAT Boots = MakeCat(age);
	cout << "Boots is " << Boots.getAge() << " years old" << endl;
	return 0;
}

CAT & MakeCat(int age)
{
	CAT *pCat = new CAT(age);
	return *pCat; // memory leak here right?
}


Style 2:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// Bug Buster

#include <iostream>

using namespace std;

class CAT
{
public:
	CAT (int age) { itsAge = age; }
	~CAT() {}
	int getAge() const { return itsAge; }
private:
	int itsAge;
};

CAT * MakeCat(int age)

int main()
{
	int age = 7;
	CAT * Boots = MakeCat(age);
	cout << "Boots is " << Boots->getAge() << " years old" << endl;
	return 0;
}

CAT * MakeCat(age)
{
	return new CAT(age);
}
Last edited on
The choice to use references or pointers is a design decision, it's not a matter of one being better than the other.

The question is, can Boots (conceptually) rebind to a different Cat? If it can, you implement that relationship using a pointer, if it can't you implement that relationship using a reference.
Last edited on
Okay, thank you for your answer. but i get another question here. does the memory leak occur at the line that i commented in the code using pointers?
Last edited on
Hi there,

i'd appreciate help with these issues myself, but if there is a memory leak in the first example (which i believe too) then it could be avoided by deleting "pCat" in the makeCat function, i think.

The Object returned still exists in the main - scope and the example still works.

Anyway,in example two, an Object of type CAT is constructed and the adress is returned to "main". If the Object is deleted in makeCAT, it will not work (although it might compile) ... if i'm not right, please notify.
But in this case, when is the Object deleted ??
The destructor for CAT must be called automatically to avoid a memory leak here.

My question: Is that the case ? "Boots" is still created dynamically .... i'm confused.
does the memory leak occur at the line that i commented in the code using pointers?
You leak that instance of Cat irrespective of whether you use a pointer or a reference.
Is there any resolution in this case? I think that i have to place the "delete pPointer" line at somewhere in the code, but where? still cant determine it.
> Is there any resolution in this case?

Yes.

Wherever possible, prefer value semantics over reference semantics.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// Bug Buster

#include <iostream>

using namespace std;

class CAT
{
public:
    explicit CAT (int age)
    {
        itsAge = age;
    }

    // ~CAT() {} // defaulted

    int getAge() const
    {
        return itsAge;
    }

private:
    int itsAge;
};

CAT MakeCat(int age) ;

int main()
{
    int age = 7;
    CAT Boots = MakeCat(age);
    cout << "Boots is " << Boots.getAge() << " years old\n" ;
}

CAT MakeCat( int age )
{
    return CAT(age);
}
If Boots is a pointer, then the delete could go in main().
1
2
3
4
5
6
7
8
int main()
{
    int age = 7;
    CAT * Boots = MakeCat(age);
    cout << "Boots is " << Boots->getAge() << " years old" << endl;
    delete Boots ;
    return 0;
}


However, I'm left feeling in this case that it might be simpler / better to put:
1
2
3
4
5
6
7
8
int main()
{
    int age = 7;
    CAT * Boots = new CAT(age);
    cout << "Boots is " << Boots->getAge() << " years old" << endl;
    delete Boots ;
    return 0;
}

Last edited on
You could use a smart pointer to manage the release. You'd probably need to do that in any event to make your code exception safe.
Topic archived. No new replies allowed.