#include <iostream>
#include <algorithm> // For std::copy
class MyResource {
public:
// Constructor
MyResource() : data(new int[100]) {//data is initialized using the member initializer list (:)
std::cout << "Constructor called\n";
}
// Destructor
~MyResource() {
delete[] data;
std::cout << "Destructor called\n";
}
// Copy constructor
MyResource(const MyResource& other) : data(new int[100]) {
std::copy(other.data, other.data + 100, data);
std::cout << "Copy constructor called\n";
}
// Copy assignment operator
MyResource& operator=(const MyResource& other) {
if (this != &other) {
std::copy(other.data, other.data + 100, data);
}
std::cout << "Copy assignment operator called\n";
return *this;
}
// Move constructor
MyResource(MyResource&& other) noexcept : data(other.data) {
other.data = nullptr;
std::cout << "Move constructor called\n";
}
// Move assignment operator
MyResource& operator=(MyResource&& other) noexcept {
if (this != &other) {
delete[] data; // Free existing resource
data = other.data; // Transfer ownership
other.data = nullptr; // Set the source to null
}
std::cout << "Move assignment operator called\n";
return *this;
}
private:
int* data; // Pointer to dynamic array of 100 integers
};
int main() {
MyResource res1; // Constructor
MyResource res2 = res1; // Copy constructor
MyResource res3;
res3 = res1; // Copy assignment
MyResource res4 = std::move(res1); // Move constructor
MyResource res5;
res5 = std::move(res2); // Move assignment
return 0; // Destructor called for all
}
#if 0
class myClass {
public:
// Constructor
myClass() : data(std::make_unique<int>(5)) {
std::cout << "Constructor called, data = " << *data << "\n";
}
private:
std::unique_ptr<int> data; // Smart pointer to manage memory automatically
};
or
myClass(){
int *data = new int(5);
std::cout << "Constructor called\n";
}
1. Local vs Member Variable:
First Constructor (myClass()):
The pointer data is a local variable inside the constructor. This means the dynamically allocated memory is lost after the
constructor finishes because data goes out of scope, and no other part of the class has access to it.
This causes a memory leak since the memory allocated by new int(5) is not deleted and there is no way to access it after the
constructor ends.
Second Constructor (MyResource()):
data is a member variable of the class (int* data; would be declared in the private or public section of the class).
The allocated memory is tied to the lifetime of the object, and you can manage it properly (e.g., freeing it in the destructor).
This is the correct approach for dynamic memory allocation when it’s supposed to be associated with the object.
2. Initialization List:
First Constructor (myClass()):
data is initialized within the body of the constructor using new int(5).
However, this data is a local variable that is never stored in the class.
Second Constructor (MyResource()):
data is initialized using the member initializer list (: data(new int[100])).
This is considered more efficient because it directly initializes the member data instead of first constructing it and then
assigning it a new value inside the constructor body.
It avoids potential performance overhead caused by reinitializing a variable that is first constructed with a default value.
3. Memory Management:
First Constructor (myClass()):
The memory allocated with new int(5) will not be properly managed since there’s no way to access or free it after the constructor ends.
The lack of a pointer at the class level or proper deletion logic results in a memory leak.
Second Constructor (MyResource()):
The dynamically allocated array (new int[100]) is assigned to the class member data, and this can be managed properly by
freeing it in the class’s destructor (delete[] data;).
This method ensures proper memory management, avoiding memory leaks.
#endif
To embed this project on your website, copy the following code and paste it into your website's HTML: