#include <iostream>
#include <cstdint>
#include <memory>
using namespace std;
class DataBlock {
public:
uint8_t* buf1;
uint8_t* buf2;
int size;
DataBlock(int n) : size(n) {
buf1 = new uint8_t[n];
buf2 = new uint8_t[n];
}
// Note: In a real scenario, we'd disable copy constructor/assignment
// to prevent double-freeing if not using smart pointers.
void set(int index, uint8_t value) {
buf1[index] = value;
buf2[index] = value;
}
void print() const {
for (int i = 0; i < size; i++) {
cout << (int)buf1[i];
if (i != size - 1) cout << " ";
}
cout << endl;
}
};
// Factory function creates object dynamically
DataBlock* createDataBlock(int n) {
return new DataBlock(n);
}
// Custom cleanup function — must be used
void cleanup(DataBlock* p) {
if (p) {
delete[] p->buf1;
delete[] p->buf2;
delete p;
cout << "Object cleaned" << endl;
}
}
int main() {
int N;
if (!(cin >> N)) return 0;
{
/**
* 1. Declare the unique_ptr with a custom deleter type.
* The syntax is: std::unique_ptr<Type, DeleterType>
* 2. Pass the cleanup function to the constructor.
*/
std::unique_ptr<DataBlock, void(*)(DataBlock*)> ptr(createDataBlock(N), cleanup);
for (int i = 0; i < N; i++) {
int temp;
cin >> temp;
// Use the -> operator to access members of the managed object
ptr->set(i, static_cast<uint8_t>(temp));
}
// Print object data
ptr->print();
// Scope ends here: cleanup(ptr.get()) is called automatically.
}
return 0;
}
Input
1 0
Expected Output
0 Object cleaned