This post was migrated from Tistory. You can find the original here.
Three ways to return an object
1. Returning a statically created object
1
2
3
4
| TestInstance TTest::getTestInstance(int i) {
TestInstance test_instance{i};
return test_instance;
}
|
1
2
3
4
5
6
7
8
9
10
11
| int main()
{
std::cout << "Hello, World!" << std::endl;
TTest t;
TestInstance t2 = t.getTestInstance(1);
t2.helloInstance();
std::cout << "Bye, World!" << std::endl;
return 0;
}
|
1
2
3
4
5
6
7
8
| Hello, World!
TTest new
TestInstance new 1
TestInstance delete 1
TestInstance hello 1
Bye, World!
TestInstance delete 1
TTest delete
|
TestInstance gets copied into new memory, and the object created inside getInstance is destroyed immediately.
2. Returning a dynamically created object
1
2
3
4
| TestInstance* TTest::getTestInstanceDynamic(int i) {
TestInstance *t = new TestInstance{i};
return t;
}
|
1
2
3
4
5
6
7
8
9
10
11
| int main()
{
std::cout << "Hello, World!" << std::endl;
TTest t;
TestInstance *t2 = t.getTestInstanceDynamic(1);
// delete t2;
std::cout << "Bye, World!" << std::endl;
return 0;
}
|
1
2
3
4
5
| Hello, World!
TTest new
TestInstance new 1
Bye, World!
TTest delete
|
If you create an object dynamically and never delete it, it won’t be destroyed until the program terminates.
1
2
3
4
5
6
7
| //when the delete line is uncommented
Hello, World!
TTest new
TestInstance new 1
TestInstance delete 1
Bye, World!
TTest delete
|
If you use new, you must always be conscious of delete.
3. Returning an object created with a smart pointer
1
2
3
4
| std::unique_ptr<TestInstance> TTest::getTestInstanceSmart(int i) {
std::unique_ptr<TestInstance> t = std::make_unique<TestInstance>(i);
return t;
}
|
1
2
3
4
5
6
7
8
9
10
| int main()
{
std::cout << "Hello, World!" << std::endl;
TTest t;
unique_ptr<TestInstance> t2 = t.getTestInstanceSmart(1);
std::cout << "Bye, World!" << std::endl;
return 0;
}
|
1
2
3
4
5
6
| Hello, World!
TTest new
TestInstance new 1
Bye, World!
TestInstance delete 1
TTest delete
|
Unless you have code that needs to delete at a specific timing, smart pointers are more reliable, since they automatically take care of deletion when the context ends.
TTest.h/cpp, TestInstance.h/cpp code
1
2
3
4
5
6
7
8
9
10
| //TTest.h
class TTest {
public:
TTest();
~TTest();
TestInstance getTestInstance(int i);
TestInstance* getTestInstanceDynamic(int i);
std::unique_ptr<TestInstance> getTestInstanceSmart(int i);
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| #include "TTest.h"
TTest::TTest() {
cout << "TTest new" << endl;
}
TTest::~TTest() {
cout << "TTest delete" << endl;
}
TestInstance TTest::getTestInstance(int i) {
TestInstance test_instance{i};
return test_instance;
}
TestInstance* TTest::getTestInstanceDynamic(int i) {
TestInstance *t = new TestInstance{i};
return t;
}
std::unique_ptr<TestInstance> TTest::getTestInstanceSmart(int i) {
std::unique_ptr<TestInstance> t = std::make_unique<TestInstance>(i);
return t;
}
|
1
2
3
4
5
6
7
8
| //TestInstance.h
class TestInstance {
public:
int idx;
TestInstance(int i);
~TestInstance();
void helloInstance();
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
| #include "TestInstance.h"
TestInstance::TestInstance(int i) : idx(i) {
cout << "TestInstance new " << idx << endl;
}
TestInstance::~TestInstance() {
cout << "TestInstance delete " << idx << endl;
}
void TestInstance::helloInstance() {
cout << "TestInstance hello " << idx << endl;
}
|