thank you for investing your time and have a nice happy new year.
Problem
The Dummy object desctructor is called to many times.
What I expect?
Dummy desctructor should be called only after item removal or when TestMap scope is ended.
What help do I need?
- Why my desctructor is called more than needed?
- How can I solve this problem?
- Does my simple array contain any more problems?
- Are there are things that could be done better in performance perspective?
Overall opinion
If anyone spots any weird parts, please comment them - I am new at c++ - that would help me to grow.
Current Code
struct Dummy {
std::string name;
std::string path;
int age;
long distance;
std::string haha;
explicit Dummy() {
std::cout << "CONSTRUCTOR DEFAULT" << std::endl;
}
explicit Dummy(std::string name) : name(std::move(name)) {
haha = randomString(10);
std::cout << "CONSTRUCTOR CUSTOM: " << haha << std::endl;
}
explicit operator std::string() const {
return name;
}
~Dummy() {
std::cout << "DESTRUCTOR: " << haha << std::endl;
}
};
template<typename T>
class TestMap {
private:
class Item {
private:
std::shared_ptr<T> _object;
public:
Item& operator=(const T& item) {
_object = std::make_shared<T>(item);
return *this;
}
Item& operator=(const T&& item) {
_object = std::make_shared<T>(std::move(item));
return *this;
}
T& get() {
return *_object;
}
inline bool isSet() const {
return _object != nullptr;
}
};
private:
Item* _values = nullptr;
size_t _capacity = 0;
size_t _size = 0;
protected:
void reallocate(const size_t& newCapacity) {
Item* newBlock = new Item[newCapacity];
for (size_t i = 0; i < _capacity; i++)
if (_values[i].isSet())
newBlock[i] = std::move(_values[i]);
delete[] _values;
_values = newBlock;
_capacity = newCapacity;
}
public:
explicit TestMap(const size_t& size = 2) {
reallocate(size);
}
void set(const size_t& key, const T& value) {
if (key > _capacity)
reallocate(key + _capacity / 2);
_values[key] = value;
}
void set(const size_t& key, const T&& value) {
if (key > _capacity)
reallocate(key + _capacity / 2);
_values[key] = std::move(value);
}
T* get(const size_t& key) {
if (key > _capacity)
return nullptr;
if (!_values[key].isSet())
return nullptr;
return &_values[key].get();
}
bool remove(const size_t& key) {
if (key > _capacity)
return false;
if (_values[key].isSet()) {
_values[key].clear();
_size--;
}
}
void clear() {
delete[] _values;
_size = 0;
_capacity = 0;
reallocate(2);
}
size_t size() const {
return _size;
}
~TestMap() {
delete[] _values;
}
};
int main() {
TestMap<Dummy> test;
{
{
Dummy abc("aaaa");
test.set(59, abc);
std::cout << "out of scope" << std::endl;
}
test.set(89, Dummy("bbbb"));
test.set(380, Dummy("cccc"));
}
std::cout << "after here everything is fine" << std::endl;
return 0;
}