如何在程序中声明/定义一次并在两个类中使用映射列表
How to declare / define once and use map list in two classes in program?
我正在C++11中开发一个程序,其中我需要在两个类中使用C++STL映射。在使用的两个位置中,地图具有相同的键和值列表。
这些类用于程序的不同部分:
// in other part of the program
void check_something()
{
// the size of the list can be 100, 200 or ...
map<string, string> amap{
{"something", "nothing"},
{"key", "value"},
};
SameClass sc{amap};
// use sc
}
// in other part of the program
void check_other_thing()
{
// the size of the list can be 100, 200 or ...
map<string, string> amap_2{
{"something", "nothing"},
{"key", "value"},
};
SameClass sx{amap_2};
// use sx
}
目前,这是可行的(用于测试),但我想知道(用于维护和优化)如何声明和定义一次,然后在程序中任何需要的地方使用映射?
我是否需要创建一个类、结构或函数,将映射放在shared_ptr<>中并返回地图?
我不想使用全局变量!
如果你想在程序中使用你的变量WHREVER,我们谈论的是全局变量,你不想使用它(这很好!)。
另一种方法是用静态变量创建类,它的工作方式类似于全局,但不会创建名称冲突
class Variables
{
private:
Variables () {} // to prevent instantiation, which makes no sense
public:
static map<string , int> myMap;
static float numba;
};
float Variables::numba = 0;
map<string , int> Variables::myMap = map<string, int>;
//somehow initialize your static variables
你像这样使用float var = Variables::numba
您也可以让函数返回对变量的引用,然后将其存储为指针。事实上,这是一个更好的想法,因为您不会使用任何类型的全局变量。
所以在某个地方创建地图,然后将其传递给对象
void setMap(map<string, string> &map) //note ampersand, it has to be a reference
{
mMap = map //where mMap means member variable in your class
}
如果您希望所有SameClass对象使用完全相同的映射,请将其设为静态变量。
正如许多评论者所建议的,常量全局变量没有错。全局变量只有在可变的情况下才是问题。既然你说数据永远不会改变,那就简单地把它们变成const
全局变量。然而,由于它们有复杂的构造函数,如果它们不是函数局部静态,则会遇到静态初始化顺序的惨败。所以修复程序看起来是这样的:
文件1:
const map<string, string>& amap() {
static const map<string,string> v {
{"something", "nothing"},
{"key", "value"},
};
return v;
}
File2(或者可能是标头)
const map<string, string>& amap();
您的映射似乎包含一种配置数据。我知道:
- 你只有一张到处都用的地图,但它到处都包含相同的日期
- 您的映射不是恒定的,所以应该可以以某种方式更改它(或在启动时加载它)
我建议您使用简单的dbconfig
类的第一个解决方案:
class dbconfig {
static map<string, string> amap; // satic: there's only one of it
public:
operator const map<string,string>& () const
{ return amap; }
// may be some functions to maintain the map
};
map<string, string> dbconfig::amap{ // there's only one such map
{"something", "nothing"}, // and it's only viisble in dbconfig
{"key", "value"}, // so totally protected
};
诀窍是使用一个转换运算符,它只返回一个只读常量。所以你可以在程序中的任何地方使用它,就像:
dbconfig cfg; // local variable. You don't have to worry about it
SameClass sc{ cfg }; // it whill be automatically converted in a reference to
// your single static map.
优点是您的配置实际上被封装在一个对象中。因此,如果需要,您可以定义一些成员来管理映射(添加或删除键)。
由于映射对外部不直接可见,而只能通过运算符进行查看,因此您可以让dbconfig对象的内部管理不断发展,而无需使用它来更改代码。例如,您可以在程序启动时保持映射为空,并在第一次请求时从配置文件或其他文件加载数据。
然而,有一个重要的悬而未决的问题:每个使用对象都应该有自己的地图副本吗?还是应该引用单个dbconfig
地图?
Otherhise表示:您是否打算动态更改地图内容,并希望所有对象都使用最新版本?
根据答案,你可以定义你的用户类来保存自己的地图副本:
class SameClass {
map<string, string> mine;
public:
SameClass (const map<string, string>& m) : mine(m) { // const ref, but local copy
...
};
或者继续使用参考:
class SameClass {
const map<string, string> & mine; // refers to the original. No own copy
public:
SameClass (const map<string, string>& m) : mine(m) { // const ref ...
};
};
经过一周的尝试,我终于解决了这个问题!
感谢所有回答的人,在这里,我根据他们的想法解决了我的问题。
我创建了一个新的头文件,并将其命名为SetMap.hpp,代码如下:
#ifndef SETMAP_HPP
#define SETMAP_HPP
#include <map>
#include <string>
struct SetMap
{
const std::map<std::string, std::string> mymap{
{"KEY_HERE","VALUE_HERE"},
};
};
#endif // SETMAP_HPP
然后,只要我需要,我就会在程序中包含这个标头,并初始化结构:
#include "SetMap.hpp"
SetMap sm;
// use as sm.mymap;
SameClass sx{sm.mymap};
SameClass的构造函数接受const映射引用,如下所示:
SameClass (const map<string, string> &m);
当我需要编辑键或值时(因为这个映射在我的程序中就像一个数据库),我只需要在一个地方编辑标题SetMap.hpp.
这样,就不需要使用全局变量,因为变量"mymap"在结构的作用域中。
这里不需要类,因为对象很小,默认情况下结构的变量是公共的。此外,如果需要添加其他具有相同"概念"(定义并声明一次)的变量,只要将其添加到结构中即可。
感谢所有花时间帮助我的人!
- 为什么在排序链表上的这种合并实现总是将两个列表都设置为 NULL,而只有一个应该设置一个列表?
- 我如何创建一个列表,然后从中创建两个列表,其中一个用于偶数,另一个用于奇数?
- 如何在两个列表中比较和获取非包含值
- 将两个列表合并为一个蛇形列表
- 使用特征查找两个列表之间的差异
- c 中的两个列表在o(1)复杂性中
- 关于合并两个列表的算法的一些问题
- 特殊使用功能 - 两个列表的产品
- 如何获取两个列表的公共元素并将其存储在新列表中而不会重复
- 使用两个列表中的组合生成函数调用
- (C++)如何创建一个函数来接收两个排序的链表并返回出现在两个列表中的第三个元素列表
- 从两个列表中随机配对
- 在有限边界下有效地合并两个列表
- 用c++合并两个列表
- 用merge在C++中合并两个列表
- 核对两个列表
- 读取Txt文件,逐行,在两个列表中存储多个类型,如果存在的话
- 在两个列表中匹配元素算法
- 比较两个列表并查找缺失元素的有效方法
- 如何在C++中应用两个列表之间的交集