c++ - 编译C++多对多类关系

标签 c++ cyclic-reference

我想知道下面的设计是如何实现的。我没有努力遵循标准约定来将这个虚拟代码保持在最低限度(例如,包括 guard )。为了论证起见,我使用的是 C++03,并且仅使用标准库组件。

TL;DR:我的 Restaurant 之间存在循环依赖关系和Recipe类。我有一个std::set<>一个指向 Recipe 对象的指针在 Restaurant类,反之亦然。我不能#include一个是另一个,但由于前向声明,编译器不允许我为集合声明一个自定义比较器,如 value_type那时 s 仍然是不完整的类型。有没有办法实现这个目标?

我在代码中添加了注释,可以更详细地解释我的问题。

/*
 * 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;

};

最佳答案

一个想法是将比较器定义移动到 .cpp 源,同时将声明保留在 header 中。这样,restaurant.hrecipe.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();
}

关于c++ - 编译C++多对多类关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17518599/

相关文章:

c++ - 在端点中将oatpp::Enum用作路径参数类型的正确方法是什么?

c++ - TXT 或 CSV 到 C++ 映射

c++ - 需要找出函数实例化的位置(gcc 4.7)

java - 构造函数注入(inject)的循环依赖

Maven 说我在多模块项目中有一个循环引用,但不知道为什么

c++ - ifstream.fail() 在 open() 之后返回 true

c++ - 重载运算符<<用于嵌套类模板

javascript - 在代码中找到一个圆形对象

java - 匿名类和父类之间的循环依赖是错误的吗?

C++ 类方法前向声明