Я наткнулся на код с открытым исходным кодом C++ и мне стало любопытно, почему люди проектируют классы таким образом?
Итак, обо всем по порядку, вот класс Abstract:
class BaseMapServer
{
public:
virtual ~BaseMapServer(){}
virtual void LoadMapInfoFromFile(const std::string &file_name) = 0;
virtual void LoadMapFromFile(const std::string &map_name) = 0;
virtual void PublishMap() = 0;
virtual void SetMap() = 0;
virtual void ConnectROS() = 0;
};
Здесь нет ничего особенного и наличие абстрактного класса может иметь несколько хорошо понятных причин. Таким образом, с этого момента я подумал, что, возможно, автор хочет поделиться общими чертами с другими классами. Итак, вот следующий класс, который является отдельным классом, но на самом деле содержит указатель типа абстрактного класса, упомянутого выше (фактический файл cpp, два других класса являются заголовочными файлами):
class MapFactory
{
BaseMapServer *CreateMap(
const std::string &map_type,
rclcpp::Node::SharedPtr node, const std::string &file_name)
{
if (map_type == "occupancy") return new OccGridServer(node, file_name);
else
{
RCLCPP_ERROR(node->get_logger(), "map_factory.cpp 15: Cannot load map %s of type %s", file_name.c_str(), map_type.c_str());
throw std::runtime_error("Map type not supported")
}
}
};
А теперь самое интересное, вот дочерний класс абстрактного класса:
class OccGridServer : public BaseMapServer
{
public:
explicit OccGridServer(rclcpp::Node::SharedPtr node) : node_(node) {}
OccGridServer(rclcpp::Node::SharedPtr node, std::string file_name);
OccGridServer(){}
~OccGridServer(){}
virtual void LoadMapInfoFromFile(const std::string &file_name);
virtual void LoadMapFromFile(const std::string &map_name);
virtual void PublishMap();
virtual void SetMap();
virtual void ConnectROS();
protected:
enum MapMode { TRINARY, SCALE, RAW };
// Info got from the YAML file
double origin_[3];
int negate_;
double occ_th_;
double free_th_;
double res_;
MapMode mode_ = TRINARY;
std::string frame_id_ = "map";
std::string map_name_;
// In order to do ROS2 stuff like creating a service we need a node:
rclcpp::Node::SharedPtr node_;
// A service to provide the occupancy grid map and the message with response:
rclcpp::Service<nav_msgs::srv::GetMap>::SharedPtr occ_service_;
nav_msgs::msg::OccupancyGrid map_msg_;
// Publish map periodically for the ROS1 via bridge:
rclcpp::TimerBase::SharedPtr timer_;
};
Так, какова цель класса MapFactory
?
Чтобы быть более конкретным - в чем преимущество создания класса, который содержит указатель типа Abstract class BaseMapServer
который является конструктором (я считаю), и этот странный конструктор создает память для нового объекта с именем OccGridServer
и возвращает его? Я так запутался, только написав это. Я действительно хочу стать лучшим C++ кодером, и я отчаянно желаю узнать секрет этих конструкций кода.