将std ::字符串转换为const char *和函数调用

converting std::string to const char * and function calls

本文关键字:char const 函数调用 std 字符串 转换      更新时间:2023-10-16

我在类中有多种需要const char *的方法,因此我将字符串转换为const char *在我的类的构造函数中,并将其存储在带有类型的const char *的本地变量中。局部变量在构造函数内部是有效的。但是,当我将其称为同一类的方法时,它是空的。

如果我使用const引用将其传递,我的问题已解决,但我希望我的代码在不使用const引用的情况下起作用。

我跟随如何将std :: string转换为const char*或char*?对于其他将字符串转换为const char *的方法。我认为c_str()正确转换字符串。

我想了解导致我的本地变量为空的根本原因。我为我的问题准备了示例代码。

与问题的代码:

#include <iostream>
#include <string>
using namespace std;
class Config{
string strFileName_ = "/path/filename.ext";
public:
    string getFileName() {return strFileName_;}
};

class Loader{
const char * className_;
public:
    Loader(string name){
        //className_ = name.c_str();   //same result with .data()
        className_ = name.data();
        cout << "[inside Loader constructor]className_ is:" << className_ << endl;
    }
    void loadFile(){
        cout << "[inside loadFile] className_ is:" << className_ << endl;
    }
};
int main(){
    Config cfg;
    Loader ld(cfg.getFileName());
    ld.loadFile();
}

用字符串而不是const char *代码没有此问题。正如我解释的那样,如果我使用const参考,问题就不再存在了。参考代码:

#include <iostream>
#include <string>
using namespace std;
class Config{
string strFileName_ = "/path/filename.ext";
public:
    const string &getFileName() {return strFileName_;}
};

class Loader{
const char * className_;
public:
    Loader(const string& name) {
        className_ = name.c_str();
        cout << "[inside Loader constructor]className_ is:" << className_ << endl;
    }
    void loadFile(){
        cout << "[inside loadFile] className_ is:" << className_ << endl;
    }
};
int main(){
    Config cfg;
    Loader ld(cfg.getFileName());
    ld.loadFile();
}
 Loader(string name){
    //className_ = name.c_str();   //same result with .data()
    className_ = name.data();

"根本原因"是由c_str()data()返回的指针指向std::string拥有的数据。当std::string被破坏时,指针不再有效。它消失了。它的内容不再存在。加入了合唱团隐形。去见了其制造商。这是一个前点。

在这里, string name是通过值参数传递给构造函数的。当构造函数返回时,此参数将被破坏。通过c_str()data()的保存指针不再是有效的指针。

对象的范围和寿命是C 的基本原理。您必须充分了解何时以及如何创建或破坏各种对象。与Java这样的其他语言不同,C 无法为您管理此问题。您必须了解何时C 程序中的各种对象被破坏,以及出于哪些原因;以及从中产生什么后果。在这里,结果是,保存的指针指向对象的内部内容会自动无效。随后使用指针会产生未定义的结果。

最好使用以下方式:

 class Config{
        string strFileName_ = "/path/filename.ext";
    public:
        string getFileName() { return strFileName_; }
    };

    class Loader{
        string className_;
    public:
        Loader(string name){
            //className_ = name.c_str();   //same result with .data()
            className_ = name.data();
            cout << "[inside Loader constructor]className_ is:" << className_ << endl;
        }
        void loadFile(){
            cout << "[inside loadFile] className_ is:" << className_ << endl;
        }
    };
    int main(){
        Config cfg;
        Loader ld(cfg.getFileName());
        ld.loadFile();
    }

其他

 class Config{
        string strFileName_ = "/path/filename.ext";
    public:
        string getFileName() { return strFileName_; }
    };

    class Loader{
        char *className_;
    public:
        Loader(string name){
            className_ = new char[name.size() + 1];
            std::copy(name.begin(), name.end(), className_);
            className_[name.size()] = ''; // don't forget the terminating 0
            cout << "[inside Loader constructor]className_ is:" << className_ << endl;
        }
        void loadFile(){
            cout << "[inside loadFile] className_ is:" << className_ << endl;
delete []className_;
        }
    };
    int main(){
        Config cfg;
        Loader ld(cfg.getFileName());
        ld.loadFile();
    }