Exceptions
#Exceptions WithWith a long and complex constructor like this, and especially one which involves I/O, things can go wrong. Carefully considering what might go wrong and using C++ exceptions has the possibility of making your code more durable.
Named variables vs. object collection
#Named variables vs. object collection
AlthoughAlthough you're using a constructor, the code looks very procedural. Instead of populating a number of named variables, consider each of those variables itself to be an object. You could store the name (e.g. "path1"
), type, and any required value checks encapsulated within individual objects, making the code easier to read, understand and maintain. I'd be inclined to use a static data structure to store and associate those things rather than burying all of those details in code. A std::map
might be appropriate.
Example code
#Example code ToTo flesh out that latter suggestion a bit, consider that you might have a string, and an unsigned int as configuration items. To refer to them, you could use just the variable names, or you could create a map:
#Exceptions With a long and complex constructor like this, and especially one which involves I/O, things can go wrong. Carefully considering what might go wrong and using C++ exceptions has the possibility of making your code more durable.
#Named variables vs. object collection
Although you're using a constructor, the code looks very procedural. Instead of populating a number of named variables, consider each of those variables itself to be an object. You could store the name (e.g. "path1"
), type, and any required value checks encapsulated within individual objects, making the code easier to read, understand and maintain. I'd be inclined to use a static data structure to store and associate those things rather than burying all of those details in code. A std::map
might be appropriate.
#Example code To flesh out that latter suggestion a bit, consider that you might have a string, and an unsigned int as configuration items. To refer to them, you could use just the variable names, or you could create a map:
Exceptions
With a long and complex constructor like this, and especially one which involves I/O, things can go wrong. Carefully considering what might go wrong and using C++ exceptions has the possibility of making your code more durable.
Named variables vs. object collection
Although you're using a constructor, the code looks very procedural. Instead of populating a number of named variables, consider each of those variables itself to be an object. You could store the name (e.g. "path1"
), type, and any required value checks encapsulated within individual objects, making the code easier to read, understand and maintain. I'd be inclined to use a static data structure to store and associate those things rather than burying all of those details in code. A std::map
might be appropriate.
Example code
To flesh out that latter suggestion a bit, consider that you might have a string, and an unsigned int as configuration items. To refer to them, you could use just the variable names, or you could create a map:
If you look at those two classes carefully, I'm sure it will be pretty easy to spot that they could have been written as a template instead.
Here's a test driver:
Here's a test driver:
If you look at those two classes carefully, I'm sure it will be pretty easy to spot that they could have been written as a template instead.
Here's a test driver:
#include <iostream>
#include <iterator>
#include <memory>
#include <string>
#include <map>
#include "ConfigItem.h"
int main()
{
std::map<std::string, std::unique_ptr<ConfigItem> > config;
config.emplace("inputFilename",
make_unique<ConfigString>(ConfigString("/var/log/messages")));
config.emplace("maxMessages",
make_unique<ConfigInt>(ConfigInt(200)));
for (const auto &it : config)
std::cout << it.first << " = " << *it.second << '\n';
int count = *config["maxMessages"];
std::cout << "count = " << count << '\n';
std::string filename = *config["inputFilename"];
std::cout << "file name = \"" << filename << "\"\n";
}
#include <iostream>
#include <iterator>
#include <memory>
#include <string>
#include <map>
#include "ConfigItem.h"
int main()
{
std::map<std::string, std::unique_ptr<ConfigItem> > config;
config.emplace("inputFilename",
make_unique<ConfigString>(ConfigString("/var/log/messages")));
config.emplace("maxMessages",
make_unique<ConfigInt>(ConfigInt(200)));
for (const auto &it : config)
std::cout << it.first << " = " << *it.second << '\n';
int count = *config["maxMessages"];
std::cout << "count = " << count << '\n';
std::string filename = *config["inputFilename"];
std::cout << "file name = \"" << filename << "\"\n";
}
#include <iostream>
#include <iterator>
#include <memory>
#include <string>
#include <map>
#include "ConfigItem.h"
int main()
{
std::map<std::string, std::unique_ptr<ConfigItem> > config;
config.emplace("inputFilename",
make_unique<ConfigString>("/var/log/messages"));
config.emplace("maxMessages",
make_unique<ConfigInt>(200));
for (const auto &it : config)
std::cout << it.first << " = " << *it.second << '\n';
int count = *config["maxMessages"];
std::cout << "count = " << count << '\n';
std::string filename = *config["inputFilename"];
std::cout << "file name = \"" << filename << "\"\n";
}