How do you put the "killing" method on?



  • Let's say there's an animal class. He inherits two classes: Predators and Travoids. Is it possible to use the method in the Predator class, which will be called to kill? Travoyal objects.



  • In principle, there's something like C++

    #include <iostream>
    using namespace std;
    struct Food {
        Food() { cout << "Food constructor" << endl; }
        ~Food() { cout << "Food destructor" << endl; }
    };
    struct Predator {
        void eat(Food& food) { food.~Food(); }
        void eat(Food* food) { delete food; }
    };
    

    int main()
    {
    Predator p;
    Food *f1 = new Food;
    Food *f2 = new Food;
    p.eat(f1);
    p.eat(f2);
    return 0;
    }

    But it's not good. There's only dynamic food available. Although you can protect yourself from UB by prohibiting the creation of food facilities on the glass:

    #include <iostream>
    using namespace std;
    struct Food {
    Food() { cout << "Food constructor" << endl; }
    void die() { delete this; }
    private:
    ~Food() { cout << "Food destructor" << endl; }
    };
    struct Predator {
    void eat(Food& food) { food.die(); }
    void eat(Food food) { food->die(); }
    };

    int main()
    {
    Predator p;
    Food *f1 = new Food;
    Food *f2 = new Food;
    // Food f3; --> compile time error
    p.eat(*f1);
    // delete f2; --> compile time error
    p.eat(f2);
    // f2->die(); --> а это скомпилируется, но UB, если f2 уже съеден
    return 0;
    }

    You can unleash the whole zoo. And in this case, the eating of an animal and its natural death are perfectly safe, the animal cannot die twice, the global function. die The shepherd and the sheep about the death of the poor:

    #include <iostream>

    using namespace std;

    struct Animal {
    virtual void eat(Animal*&) = 0;
    friend void ::die(Animal*&);
    protected:
    virtual void die() = 0;
    virtual ~Animal() {}
    };
    void die(Animal*& a);

    struct Sheep : public Animal
    {
    Sheep() { cout << "Sheep constructor" << endl; }
    void eat(Animal*&) {/* овечка не может съесть животное */ cout << "impossible" << endl;}
    protected:
    void die() { delete this; }
    private:
    ~Sheep() { cout << "Sheep destructor" << endl; }
    };

    struct Wolf : public Animal
    {
    void eat(Animal*& food) { ::die(food); }
    protected:
    void die() { delete this; }
    private:
    ~Wolf() {}
    };

    int main()
    {
    Animal *s1 = new Sheep, *s2 = new Sheep, *s3 = new Sheep;
    Animal w1 = new Wolf, w2 = new Wolf;
    w1->eat(s1);
    w2->eat(s2);
    s3->eat(w1); // Смело...
    die(s3); // От старости... Или со страху.
    die(w1); die(w2); // Отравленные овцы?!
    // w1->die(); --> ошибка компиляции
    die(w1); // --> ничего не происходит, т.к. w1==nullptr
    cout << static_cast<void
    >(w1) << endl << static_cast<void
    >(s1) << endl;
    return 0;
    }

    void die(Animal*& a) {
    if (a != nullptr)
    a->die();
    else
    cout << "Dead animal can not die. RIP" << endl;
    a = nullptr;
    }

    Thank VladD for the references:
    Here. https://isocpp.org/wiki/faq/freestore-mgmt#delete-this ♪ Here's the thing. https://isocpp.org/wiki/faq/dtors#dont-call-dtor-on-local (the truth, only local variable).




Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2