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