Suppose there is a class Animals. Two classes are inherited from it: Predators and Herbivores. Is it possible to implement the method in the Predators class, the call of which will "kill" the objects of the Herbivore class.

Closed due to the fact that the issue is too common for Kromster , pavel , aleksandr barakin , fori1ton , cheops participants Oct 28 '16 at 4:18 .

Please correct the question so that it describes the specific problem with sufficient detail to determine the appropriate answer. Do not ask a few questions at once. See “How to ask a good question?” For clarification. If the question can be reformulated according to the rules set out in the certificate , edit it .

  • 2
    And why not, in principle, you can realize anything - Mike
  • You can simply add the isAlive boolean field to the isAlive . - post_zeew
  • 2
    If your language supports deterministic object allocation, this method most likely has a destructor name. - VladD
  • four
    No, “eaten a sheep” in terms of business logic is not just the removal of an object. This should be notified to the barn (so that he makes room), the shepherd (so that he does not look for her more), perhaps, delete from other lists, too. And what exactly needs to be done - let the business logic do it. - VladD
  • one
    @VladD after eating a sheep goes into a state of "dead", and not removed. - Pavel Mayorov

1 answer 1

Basically, in C ++ you can implement something like

 #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, IMHO, this is bad. You can eat only dynamically created food). Although you can protect yourself from UB by prohibiting the creation of Food objects on the stack:

 #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; } 

And it is possible to dissolve the whole zopark))). And in this case, both the devouring of an animal and its natural death are perfectly safe, the animal cannot die 2 times, the global function of the die notifies both the shepherd and the barn about the death of the poor creature:

 #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; } 

Thanks VladD for the links: Here is the official FAQ about delete this . And what about the explicit call of the destructor (true, only a local variable).

  • Still, it's bad, just to call the destructor ... - Qwertiy
  • I don't like @Qwertiy either, by the way it is unclear why. - andy.37
  • one
    @ andy.37: I think this is not allowed by the standard. But not sure if the C ++ standard is infinite. - VladD
  • And if w1->eat(w2) ? - Qwertiy
  • @VladD, what exactly is not allowed? Just for the memory of figs you follow, and yes, it should work, sort of. - Qwertiy