C+中的面向对象类设计+; 我对C++中的类设计有一个简单的问题。

C+中的面向对象类设计+; 我对C++中的类设计有一个简单的问题。,c++,oop,C++,Oop,假设我们有以下类: class DataBase { public: DataBase(); void addEntry(const std::string& key, double value); double getEntry(const std::string& key); protected: std::map<std::string, double> table; };

假设我们有以下类:

class DataBase
{
    public:
        DataBase();


        void addEntry(const std::string& key, double value);
        double getEntry(const std::string& key);

    protected:
        std::map<std::string, double> table;
};
在这里,我感到困惑,因为我想到了两种选择:

  • SomeClass
    的每个实例都有自己的数据库。在这个意义上,只有此实例添加的数据才会出现在此数据库(专用数据库)中
  • SomeClass
    的每个实例都将引用一个中央数据库。
    SomeClass
    的任何实例添加的数据都将在一个数据库(全局数据库)中
  • 问题:

    • OOP中上述概念的名称是什么
    • 如何在C语言中实现上述每种方法++

    • 1是对象合成


      2在SomeClass声明中需要另一个Database*声明,并且两个指针都必须初始化。

      我不知道概念本身是否有名称,但成员被称为静态的非静态的
      你的1。将非静态和您的2。将是静态的

      至于如何实现这一点,您似乎知道如何使用非静态变量,对于静态变量,只需在成员声明中使用
      static
      关键字:

      class SomeClass
      {
          protected:
              static DataBase *someDataBase;
      };
      
      可以使用
      访问静态成员,如
      SomeClass::someDataBase

      class SomeClass
      {
          protected:
              DataBase someDataBase;
      };
      
      class SomeClass
      {
          private DataBase *db;
          public SomeClass();
          public SomeClass(DataBase* db);
          public ~SomeClass();
      }
      
      SomeClass::SomeClass()
      {
          this.db = new DataBase();
      }    
      
      SomeClass::SomeClass(DataBase* db)
      {
          this.db = db;
      }
      
      SomeClass::~SomeClass()
      {
          delete this.db;
      }
      

      初始化C++中的静态成员不是那么简单,但是,参见.P/>< P>我会同时提到你的两个选项:

    • 你有你的当前设置。
      SomeClass
      的每个实例都有一个指向
      数据库的指针

    • 为了实现这一点,您必须从
      SomeClass
      中取出
      DataBase
      ,因为
      SomeClass
      不再拥有数据库。对于
      数据库
      类,您将使用单例设计模式来表示“在任何时候只有这个类的一个实例”

    • 为此,您将编写数据库类,如下所示:

      class DataBase
      {
          public:
              DataBase();
              static Database * instance(); // This is the function that is used to get the global database for use.
      
              void addEntry(const std::string& key, double value);
              double getEntry(const std::string& key);
      
          protected:
              std::map<std::string, double> table;
          private:
              static DataBase * pDataBase;
      };
      

      如果你想了解更多关于单身人士的信息,请尽情阅读。

      第一个概念是组成。
      数据库
      SomeClass
      的一部分
      据我所知,2号概念车没有名字

      实施第1号概念: 这实际上非常简单:给
      SomeClass
      一个
      数据库类型的成员

      class SomeClass
      {
          protected:
              DataBase someDataBase;
      };
      
      class SomeClass
      {
          private DataBase *db;
          public SomeClass();
          public SomeClass(DataBase* db);
          public ~SomeClass();
      }
      
      SomeClass::SomeClass()
      {
          this.db = new DataBase();
      }    
      
      SomeClass::SomeClass(DataBase* db)
      {
          this.db = db;
      }
      
      SomeClass::~SomeClass()
      {
          delete this.db;
      }
      
      如果需要指针(例如多态性),请使用
      std::unique\u ptr

      class SomeClass
      {
          protected:
              std::unique_ptr<DataBase> someDataBase;
      };
      
      如果
      数据库
      无法静态初始化,或者如果不希望所有
      SomeClass
      共享同一
      数据库
      ,则可以使用对象工厂模式:

      class SomeClassFactory {
              // Constructors, etc
      
              SomeClass createSomeClass(/* args */) {
                  return SomeClass(_database, /* args */);
              }
      
          private:
              Database _database;
      // or   std::unique_ptr<Database> _database;
      };
      
      class SomeClass {
              friend class SomeClassFactory;
      
              // Private, only the factory can create SomeClass'es
              SomeClass(Database &database, /* args */)
              : database(database) {}
      
          protected:
              Database &database;
      };
      
      class类工厂{
      //建设者等
      SomeClass createSomeClass(/*args*/){
      返回SomeClass(_数据库,/*args*/);
      }
      私人:
      数据库(u)数据库;;
      //或std::unique_ptr_数据库;
      };
      上课{
      朋友级某类工厂;
      //私有,只有工厂才能创建某些类
      SomeClass(数据库和数据库,/*args*/)
      :数据库(数据库){}
      受保护的:
      数据库&数据库;
      };
      
      然后,由同一工厂创建的所有
      SomeClass
      e将共享相同的
      数据库

      class SomeClass
      {
          protected:
              DataBase someDataBase;
      };
      
      class SomeClass
      {
          private DataBase *db;
          public SomeClass();
          public SomeClass(DataBase* db);
          public ~SomeClass();
      }
      
      SomeClass::SomeClass()
      {
          this.db = new DataBase();
      }    
      
      SomeClass::SomeClass(DataBase* db)
      {
          this.db = db;
      }
      
      SomeClass::~SomeClass()
      {
          delete this.db;
      }
      
    • 使用Composition,您可以将
      数据库
      作为成员:

      class SomeClass
      {
          protected:
              DataBase someDataBase;
      };
      
      使用依赖项注入,您基本上会给
      SomeClass
      一个指向共享
      数据库的指针,而
      SomeClass
      会保存一个指向它的指针。如果您有一个多线程应用程序,请小心,您需要保护对数据库的写入,也可能保护读取

      class SomeClass
      {
          public:
          SomeClass(DataBase* db) : someDataBase(db) {}
      
          protected:
              DataBase* someDataBase;
      };
      

      <>你如何装箱,以及在哪里存储共享<代码>数据库>代码>。

      你所要寻找的是C++中的所有权主题。当我说所有权时,我指的是谁负责管理保存对象的内存

      在第一个示例中,每个
      SomeClass
      都可以拥有自己的
      数据库

      class SomeClass
      {
          protected:
              DataBase someDataBase;
      };
      
      class SomeClass
      {
          private DataBase *db;
          public SomeClass();
          public SomeClass(DataBase* db);
          public ~SomeClass();
      }
      
      SomeClass::SomeClass()
      {
          this.db = new DataBase();
      }    
      
      SomeClass::SomeClass(DataBase* db)
      {
          this.db = db;
      }
      
      SomeClass::~SomeClass()
      {
          delete this.db;
      }
      
      这个
      SomeClass
      要么拥有给定给它的数据库的所有权,要么创建它自己的数据库(实际上你通常会做一个或另一个)。这意味着您可以传入
      数据库
      对象(使用称为依赖项注入的概念):

      或者让类创建
      数据库
      对象:

      SomeClass sc();
      sc.doSomeStuffWithDB();
      
      在上面的示例中,您不必担心
      数据库
      对象的处理,因为您知道
      SomeClass
      应该在其析构函数中进行处理

      在另一种情况下,您可以共享
      数据库
      ,而不必让
      SomeClass
      处理它(不管它是全局的还是非全局的)

      在这里,我们可以将多个
      SomeClass
      对象传递给相同的
      数据库
      ,而不必担心它们被任何对象处理掉

      DataBase *db = new DataBase();
      SomeClass *sc1 = new SomeClass(db);
      SomeClass *sc2 = new SomeClass(db);
      sc1.doSomeStuffWithDB();
      delete sc1;
      sc2.doSomeStuffWithDB();
      delete sc2;
      delete db;
      

      在这个场景中,我们能够重用
      数据库
      对象,然后在
      SomeClass
      对象外部处理它。实际上,这种处理可以由另一个类(如
      DataBaseStore
      )来管理,这样您就可以有一种可靠的方法来处理和重用
      DataBase
      对象。

      当SomeClass对象添加到自己的数据库中时,您是否也希望向中央数据库对象添加相同的内容?不,我想把它们分开考虑一下,请下单解释一下我的答案有什么不对吗?2。不需要静态成员。这只是可能的实现之一,我不认为这是一个好的实现。OOP的概念被称为对象组合,谢谢,我只是不记得它的名字。所以上面的my代码代表依赖注入?@cross在某种程度上是的。一般来说,依赖项注入是一种模式,您不需要将依赖项硬编码到c语言中