- Expert C++
- Vardan Grigoryan Shunguang Wu
- 616字
- 2021-06-24 16:34:01
Initialization and destruction
As shown previously, the creation of an object is a two-step process: memory allocation and initialization. Memory allocation is a result of an object declaration. C++ doesn't care about the initialization of variables; it allocates the memory (whether it is automatic or manual) and it's done. The actual initialization should be done by the programmer, which is why we have a constructor in the first place.
The same logic follows for the destructor. If we skip the declarations of the default constructor or destructor, the compiler should generate them implicitly, which it would also remove in case they are empty (to eliminate redundant calls to empty functions). The default constructor will not be generated by the compiler if any constructor with parameters is declared, including the copy constructor. We can force the compiler to implicitly generate the default constructor:
class Product {
public:
Product() = default;
// ...
};
We also can force it not to generate the compiler by using the delete specifier, as shown here:
class Product {
public:
Product() = delete;
// ...
};
This will prohibit default-initialized object declarations, that is, Product p; won't compile.
Object initialization happens on its creation. Destruction usually happens when the object is no longer accessible. The latter may be tricky when the object is allocated on the heap. Take a look at the following code; it declares four Product objects in different scopes and segments of memory:
static Product global_prod; // #1
Product* foo() {
Product* heap_prod = new Product(); // #4
heap_prod->name = "Sample";
return heap_prod;
}
int main() {
Product stack_prod; // #2
if (true) {
Product tmp; // #3
tmp.rating = 3;
}
stack_prod.price = 4.2;
foo();
}
global_prod has a static storage duration and is placed in the global/static section of the program; it is initialized before main() is called. When main() starts, stack_prod is allocated on the stack and will be destroyed when main() ends (the closing curly brace of the function is considered as its end). Though the conditional expression looks weird and too artificial, it's a good way to express the block scope.
The tmp object will also be allocated on the stack, but its storage duration is limited to the scope it has been declared in: it will be automatically destroyed when the execution leaves the if block. That's why variables on the stack have automatic storage duration. Finally, when the foo() function is called, it declares the heap_prod pointer, which points to the address of the Product object allocated on the heap.
The preceding code contains a memory leak because the heap_prod pointer (which itself has an automatic storage duration) will be destroyed when the execution reaches the end of foo(), while the object allocated on the heap won't be affected. Don't mix the pointer and the actual object it points to: the pointer just contains the value of the object, but it doesn't represent the object.
When the function ends, the memory for its arguments and local variables allocated on the stack will be freed, but global_prod will be destroyed when the program ends, that is, after the main() function finishes. The destructor will be called when the object is about to be destroyed.
- C程序設計簡明教程(第二版)
- Azure IoT Development Cookbook
- Java高并發核心編程(卷2):多線程、鎖、JMM、JUC、高并發設計模式
- 無代碼編程:用云表搭建企業數字化管理平臺
- Ext JS Data-driven Application Design
- 區塊鏈架構與實現:Cosmos詳解
- Python深度學習
- Unity 2017 Mobile Game Development
- Scala編程(第5版)
- Mastering Docker
- Getting Started with React VR
- MongoDB Administrator’s Guide
- 零基礎PHP從入門到精通
- 少年小魚的魔法之旅:神奇的Python
- 生成藝術:Processing視覺創意入門