我正在学习C ++,我正在尝试创建一个“在线商店”,您可以在其中发布文章并对此发表评论,评论属于文章,并且文章可以包含很多评论,但是我现在不知道如何对其进行编码而不创建循环
我尝试使用Article.h-> #include“ Comment.h”,反之亦然,但是当我尝试编译它时,会创建一个循环,其中A导入B,B导入A
#include <string>
//This is what I've tried but it creates a loop
#include "Article.h"
using namespace std;
//Class
class Comment
{
private:
Article article;
string description;
string rating;
};
#include <string>
#include <map>
//The other part of my buggy-loop
#include "Comentario.h"
class Article
{
private:
map<string, int> art_comments;
string name;
string rating;
};
谢谢大家,您给我的Resolve build errors due to circular dependency amongst classes解决了我的问题
这个问题已经解决了,我该删除这个帖子吗?
答案 0 :(得分:2)
您需要退后一步。
您首先需要分析您想做什么,然后再想想如何做。然后,您将执行此操作(编写代码),然后对其进行测试。实际上,还有更多步骤。
所以让我们从WHAT开始。您有一些具有关系的实体。所以你有
那是您的实体或对象。这些实体有关系
因此,您要存储0或1或许多“东西”。为了存储这样的“东西”,C ++在STL中提供了容器。例如std :: vector或std :: list。您需要阅读这些容器的属性,并为您选择最合适的容器。在这种情况下,肯定是std :: vector。它可以包含0个或多个元素,并且可以动态增长。
对于C ++和面向对象语言中的关系,通常使用所谓的“具有”或“是”属性。通过推导对“是”关系进行建模,通过“包含”来对“具有”类型进行建模。
示例:
#include <string>
#include <vector>
// "Is a"-relation. Done by deriving from base class Shape
struct Shape
{
std::string name;
};
// A line is a shape
struct Line : public Shape
{
int length;
};
// "Has a"-relation. Done by containment. Class online Shop contains articles
struct Article
{
std::string articleName;
};
struct OnlineShop
{
std::string shopName;
std::vector<Article> article;
};
int main()
{
Line line{ "long line",12345 };
std::string myShopName{ "My Shop" };
std::vector<Article> myArticles{ Article{ "Apple"}, Article{"Banana"} };
OnlineShop myOnlineShop{ myShopName, myArticles };
return 0;
}
现在您可能会了解一些。
因此,对于您的解决方案,在考虑了实体和关系之后,您可能会得出一个可能的解决方案:
由于可能有很多文章和评论,您将把它们放在std :: vector中。然后,“在线商店”类将继续包含“评论”类的“商品”类。
因此,将没有循环依赖性。在大多数情况下,循环引用是设计缺陷的指标。
下面显示了这种实现的框架:
#include <string>
#include <vector>
struct Comment
{
std::string commentText{};
std::string commentAuthor{};
};
struct Article
{
std::string articleName{};
std::vector<Comment> comment{};
};
struct OnlineShop
{
std::vector<Article> article{};
};
int main()
{
OnlineShop onlineShop{};
return 0;
}
请根据这种方法定义您的课程。然后添加所需的功能。
还请阅读有关面向对象编程的原理。
希望这会有所帮助。 。
答案 1 :(得分:2)
这是一个很好的问题!尽管对我来说,没有太多理由让Comment了解有关Article的知识,但尤其是因为Article可能会使用std拥有其所有Comments,因此,使用对文章的引用以及正向声明可能是您要尝试做的事情。 :: vector <评论>。
现在,您的comentario.h文件如下所示:
// comentario.h
class Comment {
public:
...
private:
Article article;
[other implementation details for an Article]
}
由于您的评论绝对不应该拥有文章,因此我们可以这样重写comentario.h:
// comentario.h
class Article; // this is a forward declaration in order to reference an Article
class Comment {
public:
Comment(Article& article) // a Comment constructor--requires an Article
... // other Comment implementation details
private:
Article& article; // reference an existing Article
...
// no need for Article implementation details at all in Comment
}
// comentario.cpp
#include "include/comentario.h"
#include "include/article.h" // we can include article.h now since we're outside the header
Comment::Comment(Article& article) // the Comment constructor
: article(article) { // initialize the reference to an Article
}
这是执行此操作的一种方法。我不会亲自给Comment提供任何有关Article的知识,但是如果需要的话,我会为Article详细信息(例如标题)创建一个只读包装,然后在Comment中引用它。
旁注:许多程序员不鼓励在标头中使用“使用名称空间xx”。