Интерфейс класса куриных яиц в C

#c #class #object

Вопрос:

Мне нужна помощь в понимании синтаксиса, используемого в этой проблеме, для оценки, которую я проводил некоторое время назад.

Добавьте отсутствующий код в курицу и яйцо, чтобы завершить следующие действия:

  • Курица реализует класс Bird.
  • Курица откладывает яйцо, из которого вылупится новая курица.
  • Из яиц других видов птиц должна вылупиться новая птица их родительского типа.
  • Высиживание яйца во второй раз вызывает ошибку std::logic_error.

Это шаблон кода:

 #include <stdexcept>
#include <functional>

class Egg;

class Bird
{
public:
    virtual ~Bird(){};
    virtual Egg *lay() = 0;
};

class Egg
{
public:
    Egg(std::function<Bird *()> createBird)
    {
        throw std::logic_error("Waiting to be implemented");
    }

    Bird *hatch()
    {
        throw std::logic_error("Waiting to be implemented");
    }
};

class Chicken : public Bird
{
public:
    Chicken()
    {
    }

    Egg *lay()
    {
        throw std::logic_error("Waiting to be implemented");
    }
};

#ifndef RunTests
int main()
{
    Bird *chicken = new Chicken();

    Egg *egg1 = chicken->lay();
    Bird *childChicken1 = egg1->hatch();
}
#endif
 

Вот что я попытался сделать для выполнения некоторых задач.

 #include <stdexcept>
#include <functional>
#include <iostream>
using namespace std;

class Egg;

class Bird
{
public:
    virtual ~Bird(){};
    virtual Egg *lay() = 0;
};

class Egg
{
    int hatchCount = 0;

public:
    Egg(std::function<Bird *()> createBird)
    {
        throw std::logic_error("Waiting to be implemented");
    }

    Bird *hatch()
    {
        if (hatchCount > 0)
        {
            throw std::logic_error("This egg already hatched!");
        }
        hatchCount  ;
    }
};

class Chicken : public Bird
{
public:
    Chicken()
    {
    }

    Egg *lay()
    {
        return Egg(Chicken());
    }
};

#ifndef RunTests
int main()
{
    Bird *chicken = new Chicken();

    Egg *egg1 = chicken->lay();
    Bird *childChicken1 = egg1->hatch();
}
#endif
 

Очевидно, не так уж много. Я понимаю расширение класса Курицы из класса Птицы. Я теряюсь из-за некоторых используемых ключевых слов/синтаксиса (виртуальный? функция<Птица *()> Создать птицу??).

Для этого:

 Egg *egg1 = chicken->lay();
 

Пытаемся ли мы создать новый объект egg, обратившись где-нибудь к переменной?

Я был бы признателен, если бы кто-нибудь мог пролить свет на эту проблему!

Ответ №1:

std::function<Bird* ()> является оболочкой для лямбда-выражения. Вы можете реализовать закрытую переменную std::function<Bird* ()> hatch_egg; , например:

 class Egg
{
    int hatchCount = 0;

public:
    Egg(std::function<Bird *()> createBird) : hatch_egg(createBird)
    {
        throw std::logic_error("Waiting to be implemented");
    }

    Bird *hatch()
    {
        if (hatchCount > 0)
        {
            throw std::logic_error("This egg already hatched!");
        }
        hatchCount  ;
        return hatch_egg();
    }
private:
   std::function<Bird* ()> hatch_egg;
};
 

Способ захвата лямбды может быть выполнен с помощью синтаксиса, описанного здесь, но вкратце [params_to_be_caprutred_from_current_context](arguments to the function) -> trailing_ret_type {function body} . Оболочка называется так , как и следовало ожидать: std::function<ret_type (parameter_types)> , поэтому std::function<Bird* ()>
это функция, которая не принимает параметров и возвращает a Bird* .

Как правило, вы бы сделали что-то вроде:

 
class Chicken{
public:
    Egg* lay(){
        // We don't need any parameters from this context hence [], but if
        // we want to add a parent to the Bird object and the constructor
        // would take a Bird* then it would be like:
        // return new Egg([this]() -> Bird*{ return new Chicken(this) });
        return new Egg([]() -> Bird*{ return new Chicken; });
    }
};