I have created a config
class which loads configuration from a config YAML
.
I have created vector containers for each type
// Pseudo Code
class config
{
private:
std::vector<std::string> c_name;
public:
config(yaml_file_path)
{
// Handles reading from yaml and loading data to c_name container.
load(yaml_file_path);
}
std::vector<std::string> get_name()
{
return c_name;
}
};
I use this object in other class to get the name config.
class loadConfig
{
config cfg(yaml_file_path);
std::vector<std::string> name = cfg.get_name();
// Further use of vector name like checks.
}
Question : What would be better?(as code practice and execution time and/or memory space)
- Using
get_name()
function in various places in code. OR - Copying value in container, as I have done?
CodePudding user response:
What would be better?( as code practice and execution time and/or memory space)
Your get_name()
function does the container copy each time of the call. This is much expensive and do not required as long as you do not want to modify it outside the class.
I would suggest having one/ both of the overloads instead, so that the compiler can choose upon the (non-const/ const)object you call:
// for the non-const `config` objects call
std::vector<std::string>& get_name() /* noexcept */ {
return c_name;
}
// for the const `config` objects
const std::vector<std::string>& get_name() const /* noexcept */ {
return c_name;
}
Now at caller, you can have
auto& name = cfg.get_name(); // non-const ref for further modifications
or
const auto& name = cfg.get_name(); // const-ref for read only purposes.
In both cases, you will not copy the container.
That being said, for the classes such as config
, which has only one container as internal storage, my personal favorite would be making the class iterable by providing the begin
and end
overloads:
class config
{
std::vector<std::string> c_name;
public:
auto begin() noexcept { return c_name.begin(); }
auto cbegin() const noexcept { return c_name.cbegin(); }
auto end() noexcept { return c_name.end(); }
auto cend() noexcept { return c_name.cend(); }
};
This makes the you write code such as>
config names;
for (auto& name : names) // or for (auto const& name : names)
{
// ...do something with names
}