The config design in C + +

Source: Internet
Author: User
Tags map data structure

The configuration file read-write class, which has the following methods:

1. Ability to read into a specified configuration file

2. Support the ability to add a configuration item at any time

3. Strong enough to write configuration information for various data structures

In C + +, we use STD::MAP to store such data.

That is, in our Config class, we need to have a basic and basic STD::MAP member that stores the configuration file key value to the information, which is used to record each key value in the configuration file and its corresponding value value.

Then another question is coming, what kind of std::map should we be?

Haha, this problem is actually very simple, because our key value to the information is read out to write to the file, then std::map whether the key value or value will be a string type, that is, C + + STL std::string (Config class does not support Chinese encoding) class.

Then someone would ask, if the value is just a simple std::string class, I want to store a very complex data structure, such as a phone key value, corresponding to a list of phone numbers?

The problem is also very simple, where the STD::MAP member is just the most basic of the Config class stored in the file string key value pair record, and Config in order to support the user to store a variety of complex value values, also provides template support. Therefore, only the structure of the value you supply here can be converted to the std::string type, you can use the Config class to store your data structure.

So let's look at the code for the Config class:

std::string m_Delimiter;  //!< separator between key and value  std::string m_Comment; //!< separator between value and comments std::map<std::string, std::string> m_Contents; //!< extracted keys and values 
    • 1
    • 2
    • 3

These three internal properties, which are the settings for the m_Delimiter delimiter of the key and value values we mentioned earlier, are the settings for the first = m_Comment character of the comment content we mentioned earlier, which is the # m_Contents Std::map object We discussed above, and with key Values and value values are stored as std::string types.

In addition, so many of the template functions we see in the Config class, which ultimately want to be implemented, are to support the read and write of the user-defined value data structure:

//!<Search for key and read value or optional default value, call as read<T>  template<class T> T Read(const std::string& in_key) const; // Modify keys and values template<class T> void Add(const std::string& in_key, const T& in_value);
    • 1
    • 2
    • 3
    • 4

This intercepts two important functions, one for reading the value of the key value, and one for adding a key-value pair. As you can see, the key value here is always an object of type std::string, and the corresponding value value is the type defined by the template, enabling the user to customize any data structures that can be transferred to the std::string type.

Third, the design of the Config: Exposure method

Next, let's consider a problem where we see the contents of the configuration file and abstract it into the STD::MAP data structure, and what we need to do is to expose the method to callers of the class.

So what are the ways to do it:

1. A constructor that can be bound to a specific configuration file

2. Get the value of the specified key value

3. Add a pair of key-value pairs

4. Modify the value of the specified key value

5. Delete a pair of key-value pairs

For the time being it is important to think about these, so how do you provide these methods in the Config class?

Haha, provided, let's look at it one by one:

1. A constructor that can be bound to a specific configuration file

Config::Config(string filename, string delimiter, string comment)    : m_Delimiter(delimiter), m_Comment(comment){    // Construct a Config, getting keys and values from given file      std::ifstream in(filename.c_str()); if (!in) throw File_not_found(filename); in >> (*this);}
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

The author uses Std::ifstream to open a local file, noting that the file must be guaranteed to exist before calling this method. We should note that the author invokes the in >> (*this) operator>> overloaded function of this class to read the contents of the file (the function is too verbose to view the source code itself) and store it in the Std::map

!<search for key and read value or optional default value, call as Read<t>template<class t> T Read ( Const std::string& In_key) CONST; template<class t> T Read ( Const std::string& In_key, const t& in_value) CONST; template<class t> bool Readinto (t& Out_var, const STD:: string& In_key) const;             
    • 1
    • 2
    • 3
    • 4

These three are template functions, which are primarily used to obtain the value of a user-defined data structure. It should be noted that the use of these three functions, the first one is to return value values, the second is that the value values can be returned in the parameter, and the third directly writes value value to the incoming var object.

3. Add a pair of key-value pairs
4. Modify the value of the specified key value
The author uses a function directly to complete the work of the 3rd and 4th:

template<class T>void Config::Add(const std::string& in_key, const T& value){ // Add a key with given value std::string v = T_as_string(value); std::string key = in_key; Trim(key); Trim(v); m_Contents[key] = v; return;}
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

The Std::map feature of C + + is used here, and if the key value exists in Std::map, the value is updated, otherwise a pair of key-value pairs is added. It is important to note that this line of code is called:

std::string v = T_as_string(value);
    • 1

Where the function converts a T_as_string user-passed custom template class into a std::string type for storage, the method is implemented as follows:

/* static */template<class T>std::string Config::T_as_string(const T& t){ // Convert from a T to a string // Type T must support << operator std::ostringstream ost; ost << t; return ost.str();}
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

This class directly invokes the operator<< overloaded operator function of the user-defined template class, which means that the Config class can be used for value as long as the user-defined data structure custom overloads the operator<< operator function. Read-write operation of the value.

5. Delete a pair of key-value pairs

void Config::Remove(const string& key){    // Remove key and its value      m_Contents.erase(m_Contents.find(key));    return;}
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

Fortunately there is a powerful C + + STL function, delete a pair of key-value pairs is so simple.

6. A few other methods
For the convenience of users, the author also provides methods such as querying the existence of a file, the existence of a key value, the reading of a file, setting the Get key value delimiter, setting the Get comment identifier, and so on. are relatively simple and easy to use, interested students can view the source code themselves.

Iv. Use of Config Demo

Here, I wrote a Demo on my own to test the functions of the Config class:

#include <iostream>#include <cstdlib>#include <string>#include <fstream>#include "Config.h"int main () {Open a write file stream pointing to the Config.ini fileSTD::String Strconfigfilename ("Config.ini");Std::ofstream out (strconfigfilename);Initialize write comment out <<"# test for config read and write\n";Write a pair of configuration records: name = wangying out <<"name = wangying\n"; Out.close ();Initializes the Config Class Config config (strconfigfilename);Reading key valuesSTD::String strkey ="Name";STD::String strvalue; strvalue = config. read<STD::String> (strkey);STD::cout <<"Read Key" << strkey <<"' s Value is" << strvalue <<Std::endl;Write new key value pairSTD::string strnewkey =  "age"; std::string strnewvalue =  "23"; Config. Add<std::string> (Strnewkey, strNewValue); //write modifications to the Config class to the file Out.open (strconfigfilename, std::ios::app); Span class= "Hljs-keyword" >if (Out.is_open ()) {//take advantage of the Config class << overloaded operator out << conf Ig std::cout <<  "Write Config content success! "<< STD::ENDL;} out.close (); System ( "pause"); return 0;}         
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21st
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

Fortunately there is a strong config class, let me manipulate the configuration file into a simple thing!

However, it is important to note that after we use the Config class for the ADD () operation, we simply manipulate the contents of the M_contens object of the Std::map type in the Config class, and we need to write it to the file. So here I finally called the write file stream for write operations, note this line of code:

// 利用 Config 类的 << 重载运算符out << config;
    • 1
    • 2

The operator<< overloaded operator for the Config class is implicitly called:

std : :ostream& operator<< (STD: :ostream& os, const config& CF) { //save a Config to OS for (config::mapci p = cf.m_contents. Begin (); P! = cf.m_contents. end (); ++p) {OS << p->first <<  "<< cf.m_delimiter << " "; Os << p->second << std::ENDL;} return os;}              

Config design in C + +

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.