C++ 在代码中管理硬编码文件路径/名称

C++ 在代码中管理硬编码文件路径/名称,c++,C++,我正在寻找在代码中处理硬编码文件路径/名称的最佳方法。将来它们将是用户输入,但现在它们只是硬编码的代码。我有以下可能的选择: 将它们声明为私有类成员,并通过构造函数初始化它们 在名称空间内声明和初始化它们,并通过名称空间访问它们 将它们声明为公共类成员,并通过访问公共成员对其进行初始化 还有其他可能的做法吗 我知道最好的选择取决于代码的细节,但我正在寻找一些想法来选择一个。始终在这些数据周围放置一个包装函数。函数获取数据的方式可以很容易地修改,而不会影响函数的用户 如果对象的所有实例的文件名

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

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

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

始终在这些数据周围放置一个包装函数。函数获取数据的方式可以很容易地修改,而不会影响函数的用户

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


如果文件名可以不同于对象的一个实例到下一个实例,则将函数设置为常规成员函数。

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

#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
#包括
#包括
#包括
#包括
类文件路径{
std::无序映射m_mstrfilepath;
公众:
文件路径();
~filepath();
std::string getPath(const std::string&strId)const;
void addPath(const std::string和strFilePath);
私人:
文件路径(const filepath&c);
文件路径和运算符=(常量文件路径和c);
}; // 文件路径
静态无符号uId=0;//初始化为0-这应该在class.cpp文件中!
文件路径::文件路径(){
m_mstrfilepath.clear();
}//文件路径
文件路径::~filepath(){
m_mstrfilepath.clear();
}//~文件路径
std::string文件路径::getPath(const std::string&strId)const{
if(strId.empty()){
//返回错误或如果在Try-Catch块中抛出错误
返回std::string();
}
std::无序映射::常量迭代器it=m\u mstrfilepath.find(strId);
if(it==m_mstrfilepath.cend()){
//找不到
//返回错误或如果在Try-Catch块中抛出错误
返回std::string();
}
返回->秒;
}//获取路径
void filepath::addPath(const std::string和strFilePath){
if(strFilePath.empty()){
//返回错误或如果在Try-Catch块中抛出错误
返回;
}
std::ostringstream strStream;

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

这可能是(反模式)创建一个拥有全局配置参数的对象。我不太了解C++,但你能用一个配置文件吗?@ diutl uccw我只想确保我理解:所以这个想法是创建一个类,它包含成员来存储配置参数,然后实例化该类的对象。ht?我读了几遍,但还不清楚如何实现包装器函数。@user4838962,发布一些您尝试过的代码。当我看到一些代码时,用代码回答会更容易:)我个人更进一步。我会为那些硬编码的名称/路径编写一个带有访问函数的占位符类。确保接口将对该占位符类的引用向下传递到您的算法中。您可以调用方法来获取硬编码字符串等。当用户界面完成后,它可以truct实际类并用用户输入填充字符串。有些人喜欢将此占位符设置为单例。我更喜欢根据需要通过引用将其传递到CTOR中。我使用无序映射而不是向量的原因是,您可以通过返回适当字符串的字符串索引找到路径!用户将要了解映射的索引!另外,稍后当您决定允许用户输入添加到文件路径中时,您可以使用cin或get行调用,并将其保存到一个字符串中,将其直接传递到此类addPath()中方法.Example对我帮助很大。我想知道这是否可行:在我的原始类中,我用包装类的类型声明一个
静态
成员,这样原始类的所有实例的文件名/路径都可以相同。这是避免使用singleton的另一种方法吗?我觉得不可能声明成员E > C++中的另一类中的类型类的static < /COD>成员。可以嵌套类。如果只在一个特定类中需要这个类,那么可以使该类既受保护又私有,但必须在现有类中使用公共方法调用该类的方法。我认为不需要静态成员。nce只要父类在作用域中,该嵌套类就可以存在。您也可以将其作为单独的类,并将其作为私有成员变量,该变量可以是唯一的_ptr()。您可以在一个类中拥有指向另一个类的静态指针,但您指向的类必须具有静态get()方法,该方法将在构造时返回其(this)指针。