管理代码中的硬编码文件路径/名称

managing hard-coded file paths/names in code

本文关键字:文件 路径 名称 编码 代码 管理      更新时间:2023-10-16

我正在寻找在代码中处理硬编码文件路径/名称的最佳方法。在未来,它们将是用户输入,但目前它们只是硬编码的代码。我有以下可能的选择:

  • 将它们声明为私有类成员,并通过构造函数初始化它们
  • 声明&在命名空间中初始化它们,并通过命名空间访问它们
  • 将它们声明为公共类成员,并通过访问公共成员来初始化它们
  • 还有其他可能的做法吗

我知道最好的选择取决于代码的细节,但我正在寻找一些想法来选择一个。

Always在此类数据周围放置一个包装函数。函数获取数据的方式可以很容易地修改,而不会让函数的用户感到不安。

如果对象的所有实例的文件名都相同,请将该函数设置为静态成员函数。

如果对象的一个实例和下一个实例的文件名可能不同,请将该函数设置为常规成员函数。

下面是一个工作包装类的例子!

#include <unordered_map>
#include <sstream>
#include <string>
#include <iostream>
class FilePaths {
std::unordered_map<std::string, std::string> m_mStrFilePaths;
public:
FilePaths();
~FilePaths();
std::string getPath( const std::string& strId ) const;
void addPath( const std::string& strFilePath );
private:    
FilePaths( const FilePaths& c );
FilePaths& operator=( const FilePaths& c );
}; // FilePaths

static unsigned uId = 0; // Initialize to 0 - This should be in your class.cpp file!
FilePaths::FilePaths() {
m_mStrFilePaths.clear();
} // FilePaths
FilePaths::~FilePaths() {
m_mStrFilePaths.clear();
} // ~FilePaths
std::string FilePaths::getPath( const std::string& strId ) const {
if ( strId.empty() ) {
// Return Error Or If In Try Catch Block Throw Error    
return std::string();
}
std::unordered_map<std::string, std::string>::const_iterator it = m_mStrFilePaths.find( strId );
if ( it == m_mStrFilePaths.cend() ) {
// Not Found
// Return Error Or If In Try Catch Block Throw Error    
return std::string();
}
return it->second;
} // getPath
void FilePaths::addPath( const std::string& strFilePath ) {
if ( strFilePath.empty() ) {
// Return Error Or If In Try Catch Block Throw Error    
return;
}
std::ostringstream strStream;
strStream << "Id_" << ++uId;
m_mStrFilePaths[strStream.str()] = strFilePath;
} // addPath
int main( int argc, char** argv ) {
FilePaths paths;
// I have double slashes in the strings here because of the escape sequence /P
paths.addPath( std::string( "C:\PathA" ) );
paths.addPath( std::string( "C:\PathB" ) );
paths.addPath( std::string( "C:\PathC" ) );
std::string myPath = paths.getPath( std::string( "Id_2" ) );
std::cout << myPath << std::endl;
// Has No Meaning - I put a break point on this line to stop execution from closing the console.
std::cout << "Pause On This Line" << std::endl;
return 0;
} // main

现在,如果你想对此更严格一点,你可以从一个基类继承这个类,这个基类是一个单例,所以你只能创建这个对象的一个实例,但你需要在这个类中定义一个静态的get方法,它会在构造时返回这个类指针。然后,您可以在项目中任何需要的地方使用const全局指针。

最好有一个错误处理类来捕获和抛出异常!这样,如果要存储的路径或要查找的字符串id无效,则会引发异常。现在,您不必使用字符串作为ID,您可以使用无符号int,并将此映射中的这些无符号int键值与全局枚举相关联,但这操作更简单,读取和使用也更友好。

这应该让你开始,我希望这有帮助!

在阅读本文后,我将这个类的一个方法从setPath更新为addPath。我更改了这一点,因为set听起来更像是将单个值设置到单个成员变量中,而add听起来更像将元素放入容器中。它只是出于偏好的原因,而不是现有的代码是错误的或不起作用。

另一种可以帮助您的方法是将所有FilePaths都放在一个文本文件中,每个文件都在自己的行上,并以回车结束。然后编写一个小的解析器函数,逐行读取文本文件,读取每一行的内容并将其保存到字符串中。然后,在获得该字符串后,可以使用上面的包装器类通过传递从解析器获得的字符串来存储其内容。这样,如果你需要修复或更改FilePath,你只需编辑文本文件,每次更改或添加FilePath时都不必重新编译或重建代码!这将创建一个自动过程!