jak stworzyć parę ze skomplikowanych obiektów?

0

Hej
Pytanie typowo z rozmowy kwalifikacyjnej. Jak stworzyć poniżej parę by nie wywalał się błąd kompilacji "no matching function for call..."?

#include <stdio.h>
#include <iostream>
#include <string>
#include <map>
#include <utility>

using namespace std;

class Klasa
{
    public:
    Klasa():x(nullptr)
    {
        std::cout << "default ctor" << std::endl;
    }
    Klasa(int* x):x(x)
    {
        std::cout << "ctor x=" << x << std::endl;
    }
    
    ~Klasa()
    {
        std::cout << "dtor x=" << x << std::endl;
        delete x;
    }

    Klasa(Klasa&& kl)
    {
        std::cout << "move ctor" << std::endl;
        delete x;
        x=kl.x;
        kl.x=nullptr;
    }
    
    Klasa(const Klasa& kl)
    {
        std::cout << "copy ctor" << std::endl;
        *x=*kl.x;
    }
    
    Klasa& operator=(Klasa&& kl)
    {
        std::cout << "move assignment operator" << std::endl;
        delete x;
        x=kl.x;
        kl.x=nullptr;
        return *this;
    }
    
    Klasa& operator=(const Klasa& kl)
    {
        std::cout << "copy assignment operator" << std::endl;
        *x = *kl.x;
        return *this;
    }
    
    void print() const
    {
        std::cout << x << std::endl;
    }

    int get() const
    {
        if(x!=nullptr)
            return *x;
            
        return 0;
    }
    
    private:
        int* x;
};

int main()
{
    pair<Klasa, string> para = pair<Klasa, string>(Klasa(new int(2)), "cccc"); //to sie nie kompiluje

map<Klasa, string, bool (*)(const Klasa&, const Klasa&)> 
        mapa([](const Klasa& left, const Klasa& right){return left.get()<right.get();});
    mapa.insert(make_pair(new int(2), "ddd"));  //to niby sie kompiluje ale double free or corruption wyskakuje przy egzekucji
    return 0;
}
0

Jesteś pewien, że to ten kod? Skopiowałem, skompilowałem i nie ma żadnego błędu.

2

U mnie się kompiluje, ale asan narzeka na UB w konstruktorze przenoszącym (delete x gdzie x nie ma wartości)

1

Jeśli to kod, który dostałeś do poprawienia podczas rekrutacji, to lepiej szukaj innej firmy.
Jeśli to coś, co ty napisałeś podczas rekrutacji, to jakie miałeś zadanie? Co miał realizować kod i czemu jest tak przekombinowany?

0

błąd byl w konstruktorze kopiującym i kopiującym operatorze przypisania, brakuje tam deklaracji pamięci dla x.
No i w konstruktorze przenoszącym nie robi się delete'a. O tym zapomniałem.
Takie dają zadania na rekrutacji, żeby np. stworzyć mapę gdzie kluczem jest twoja klasa zawierająca wskaźnik, żeby zobaczyć czy ubiegający się o pracę jest w stanie napisać dla mapy predykator, zdefiniować konstruktory itp.

2
fvg napisał(a):

Takie dają zadania na rekrutacji, żeby np. stworzyć mapę gdzie kluczem jest twoja klasa zawierająca wskaźnik, żeby zobaczyć czy ubiegający się o pracę jest w stanie napisać dla mapy predykator, zdefiniować konstruktory itp.

Zadanie może i głupie (ale to wynika z limitu czasu), ale twoja odpowiedź jest po prostu słaba.
Popatrz na coś takiego:

#include <iostream>
#include <map>
#include <memory>

using namespace std::literals;

template<typename T>
class Foo {
public:
    Foo(std::unique_ptr<T> p) : p{std::move(p)}
    {}
    
    T& get()
    {
        return *p;
    }
    
    const T& get() const
    {
        return *p;
    }

private:
    std::unique_ptr<T> p;
};

template<typename T>
struct FooLessCmp
{
    bool operator()(const Foo<T>& a, const Foo<T>& b) const
    {
        return a.get() < b.get();
    }
};

template<typename K, typename V>
using FooMap = std::map<Foo<K>, V, FooLessCmp<K>>;

int main()
{
    FooMap<int, int> a;
    a[std::make_unique<int>(3)] = 2;
    a[std::make_unique<int>(2)] = 3;

    std::cout << a[std::make_unique<int>(3)] << '\n';
    
    return 0;
}

https://wandbox.org/permlink/C4CtC3J986jLVWez

Okraszając to odpowiednimi technicznymi wyjaśnieniami, można pokazać, że się wie co się robi. Np wspomnieć i wyjaśnić "Rule of zero".

1 użytkowników online, w tym zalogowanych: 0, gości: 1