如何将A和B中的A实现为A(不创建循环)?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (12)

我正在学习C ++,我正在尝试创建一个“在线商店”,你可以发表文章并对它们发表评论,评论属于文章,文章可以有很多评论,但我现在不知道如何编写它创建一个循环

我尝试过使用Article.h - > #include“Comment.h”,反之亦然,但是当我尝试编译时会创建一个循环,其中A导入B和B导入A

Comment.h

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

Article.h


#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;
};
提问于
用户回答回答于

这是一个很好的问题!使用对文章的引用以及前向声明可能就是你要做的事情,尽管我没有看到评论对文章有任何了解的原因,特别是因为文章可能会使用std拥有它的所有评论:: 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

}

这是一种方法。我个人不会对文章的任何知识发表评论,但是如果必须的话,我会创建一个只读的文章详细信息包装,如标题,然后在评论中引用。

旁注:许多程序员不鼓励在头文件中使用“命名空间xx”。

用户回答回答于

你需要返回到上一步。

你需要先分析你想做什么,然后想想你能做什么。然后你会这样做(编写代码),然后你会测试它。实际上还有更多的步骤。

那么让我们从WHAT开始吧。你有一些有关系的实体。所以你有了

  • 一个“在线商店”
  • “文章”和
  • “评论”为“文章”

那是你的实体或对象。这些实体有关系

  • 在线商店有0或1或多篇文章
  • 现有文章可以包含0或1个或多个注释

所以,你想存储0或1或许多“某事”。为了存储这样的“东西”,C ++在STL中提供了容器。例如std :: vector或std :: list。您需要了解这些容器的属性并选择最适合您的容器。在这种情况下,它肯定是std :: vector。它可以包含0个或更多元素,并且可以动态增长。

对于C ++和面向对象语言中的关系,大多数人都使用“has a”或“is a”属性。“是一种”关系是用推导建模的,“有一种”类型是通过所谓的包含来建模的。

例:

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

现在你可能会更好理解了。

因此,对于您的解决方案,在考虑了实体和关系后,您可能会找到一个可能的解决方案:

  • 您将创建一个类OnlineStore
  • 您将创建一个类文章
  • And a class Comment

Since there are possibly many Articles and many Comments, you will put those in a std::vector. And the class OnlineShop will conatin the class Article which will contain the class Comment.

As a result there will be no circular dependencies. Circular references are in most cases an indicator for a design flaw.

The below shows an skeleton of such implementation:

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

Please define your classes based on this approach. Then add the needed functionality.

Please also read about the principles of object oriented programming.

Hope this helps a little . . .

扫码关注云+社区

领取腾讯云代金券