[英]Compiling C++ many to many class relations
I want to know how to achieve the following design. 我想知道如何实现以下设计。 I have not put effort to follow the standard conventions in order to keep this dummy code to a minimum (eg, include guards).
为了使此伪代码降至最低(例如,包括防护),我没有付出任何努力遵循标准约定。 For arguments sake, I am using C++03, and only standard library components.
为了论证,我使用的是C ++ 03,并且仅使用标准库组件。
TL;DR : There is a cyclic dependency between my Restaurant
and Recipe
classes. TL; DR :我的
Restaurant
和Recipe
类之间存在循环依赖关系。 I have a std::set<>
of one pointers to object of Recipe
in the Restaurant
class, and vice-versa. 我在
Restaurant
类中有一个std::set<>
指向Recipe
对象的指针,反之亦然。 I cannot #include
one in the other, but due to the forward declaration, the compiler doesn't allow me to declare a custom comparator for the collections, as the value_type
s are still incomplete types at that point. 我不能
#include
一个,但由于前向声明,编译器不允许我为集合声明一个自定义比较器,因为value_type
当时仍是不完整的类型。 Is there a way to achieve this? 有没有办法做到这一点?
I've included comments in code which explain my issue in more detail. 我在代码中添加了注释,这些注释更详细地说明了我的问题。
/*
* restaurant.h
*/
#include <string>
#include <set>
/*
* I cannot do this as recipe.h would need to include
* restaurant.h, which restricts
* me when I want to write a custom comparator.
*/
// #include "recipe.h"
class Recipe;
// I know this will not work as Recipe has not yet been declared.
struct RecipeComparator {
bool operator() (const Recipe* lhs, const Recipe* rhs) {
return lhs->price() < rhs->price();
}
};
class Restaurant {
public:
Restaurant(const std::string& name, float averagePrice);
float averagePrice() { return m_averagePrice; }
private:
std::string m_name;
float m_averagePrice;
/*
* I want to have the recipies sorted by their prices.
* I cannot define RecipeComparator here as Restaurant
* is an incomplete type till now.
*/
std::set< Recipe*, RecipeComparator > m_recipiesSorted;
/*
* This works, but does not do what I want.
*/
std::set< Recipe* > m_recipies;
};
/*
* recipe.h
*/
#include <string>
#include <set>
/*
* I cannot do this as restaurant.h would need to include
* recipe.h, so I need to forward declare, which restricts
* me when I want to write a custom comparator.
*/
// #include "restaurant.h"
class Restaurant;
// I know this will not work as Restaurant has not yet been declared.
struct RestaurantComparator {
bool operator() (const Restaurant* lhs, const Restaurant* rhs) {
return lhs->averagePrice() < rhs->averagePrice();
}
};
class Recipe {
public:
Recipe(const std::string& name, float price);
float price() { return m_price; }
private:
std::string m_name;
float m_price;
/*
* This is what I want as I want to have the restaurants sorted
* by their average prices.
* I cannot define RestaurantComparator here as Restaurant
* is an incomplete type till now.
*/
std::set< Restaurant*, RestaurantComparator > m_restaurantsSorted;
/*
* This works, but does not do what I want.
*/
std::set< Restaurant* > m_restaurants;
};
One idea is to move your Comparator definitions to a .cpp source while keeping the declarations in the header. 一种想法是将比较器定义移动到.cpp源,同时将声明保留在标头中。 This way,
restaurant.h
and recipe.h
will still only refer to each other by name and so a forward declare will still be enough. 这样,
restaurant.h
和recipe.h
仍仅按名称相互引用,因此前向声明仍然足够。
// restaurant_recipe_comparators.h
// probably too long, give it a better name
struct RestaurantComparator
{
bool operator() (const Restaurant *, const Restaurant *);
};
struct RecipeComparator
{
bool operator() (const Recipe *, const Recipe *);
};
// restaurant_recipe_comparators.cpp
bool RestaurantComparator::operator() (const Restaurant* lhs, const Restaurant* rhs)
{
return lhs->averagePrice() < rhs->averagePrice();
}
bool RecipeComparator::operator() (const Recipe* lhs, const Recipe* rhs)
{
return lhs->price() < rhs->price();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.