C++ 将std::string转换为const char*和函数调用

C++ 将std::string转换为const char*和函数调用,c++,string,function,c++11,pointers,C++,String,Function,C++11,Pointers,我的类中有多个需要const char*的方法,因此我在类的构造函数中将string转换为const char*,并将其存储在一个const char*类型的局部变量中。局部变量在构造函数中有效。但是,当我对同一类的方法调用它时,它是空的 如果我使用常量引用传递它,我的问题就解决了,但我希望我的代码在不使用常量引用的情况下工作 我遵循其他方法将字符串转换为const char*。我认为c_str()可以正确地转换字符串 我想了解导致局部变量为空的根本原因。 我为我的问题准备了示例代码 有问题的代

我的类中有多个需要const char*的方法,因此我在类的构造函数中将string转换为const char*,并将其存储在一个const 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();
}
#包括
#包括
使用名称空间std;
类配置{
字符串strFileName_u173=“/path/filename.ext”;
公众:
string getFileName(){return strFileName_;}
};
类加载器{
常量字符*className\ux;
公众:
加载器(字符串名称){
//className_u979;=name.c_str();//与.data()的结果相同
className_u979;=name.data();
不能更好地使用这个:

 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();
    }
类配置{
字符串strFileName_u173=“/path/filename.ext”;
公众:
string getFileName(){return strFileName_;}
};
类加载器{
字符串类名称;
公众:
加载器(字符串名称){
//className_u979;=name.c_str();//与.data()的结果相同
className_u979;=name.data();
不能更好地使用这个:

 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();
    }
类配置{
字符串strFileName_u173=“/path/filename.ext”;
公众:
string getFileName(){return strFileName_;}
};
类加载器{
字符串类名称;
公众:
加载器(字符串名称){
//className_u979;=name.c_str();//与.data()的结果相同
className_u979;=name.data();
库特
“根本原因”是
c_str()
data()返回的指针
指向属于
std::string
的数据。当
std::string
被破坏时,指针不再有效。它消失了。它的内容不再存在。加入了不可见的唱诗班。去见它的制作者。它是一个前指针

此处,
字符串名称
通过value参数传递给构造函数。当构造函数返回时,此参数将被销毁。通过
c_str()
data()
保存的指向其内容的指针不再是有效的指针

<> P>对象的范围和生命周期是C++的一个关键的基本原理。你必须完全理解各种对象何时和如何被创建或破坏。C++不为你管理这些,不像其他java语言那样。你必须理解C++程序中的各种对象何时被破坏,以及原因。因此,结果是保存的指向对象内部内容的指针自动失效。后续使用指针会产生未定义的结果

“根本原因”是
c_str()
data()返回的指针
指向属于
std::string
的数据。当
std::string
被破坏时,指针不再有效。它消失了。它的内容不再存在。加入了不可见的唱诗班。去见它的制作者。它是一个前指针

此处,
字符串名称
通过value参数传递给构造函数。当构造函数返回时,此参数将被销毁。通过
c_str()
data()
保存的指向其内容的指针不再是有效的指针


<> P>对象的范围和生命周期是C++的一个关键的基本原理。你必须完全理解各种对象何时和如何被创建或破坏。C++不为你管理这些,不像其他java语言那样。你必须理解C++程序中的各种对象何时被破坏,以及原因。因此,结果是指向对象内部内容的保存指针自动失效。后续使用指针会产生未定义的结果。

请告诉我为什么不能只使用
std::string
?使用
const char*
有什么好处?您的确切意思是什么“它是空的”?是代码> null <代码>还是代码> null pTr> /Cube >?使用什么平台/C++编译器/运行时?根据,<代码>名称>数据()(代码)>返回一个“分配的拷贝”:数组的第一个元素的第一个元素的点,其第一个元素是由代码的原始值指向的,STR.DATA()
。由于它是一个分配的副本,我认为在新对象的构造函数完成后,无论源
字符串
对象发生什么情况,它都应该是有效的。我需要const char*,因为我使用需要这种格式的PETSc库。但是,我的问题与PETSc库无关,它是通用的。我使用g++(GCC)5.3.1使用c++11的20160406(Red Hat 5.3.1-6)。我检查了该值,它不为空。请告诉我为什么不能只使用
std::string
?使用
const char*
有什么好处?您所说的“它是空的”到底是什么意思“是代码<空NU/CODE >还是<代码> null pTr> /CODE?您使用的是哪个平台/C++编译器/运行时?根据, No.DATA()(代码)>应该返回一个“分配的副本”:在数组的第一个元素的第一个元素点上,其第一个元素被“代码”的原始值指向STR.DATA()。
。由于它是一个分配的副本,我认为在新对象的构造函数完成后,无论源
字符串
对象发生什么情况,它都应该是有效的。我需要const char*,因为我使用需要这种格式的PETSc库。但是,我的问题与PETSc库无关,它是通用的。我使用g++(GCC)5.3.1 20160406(红帽5.3.1-
 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()] = '\0'; // 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();
    }
 Loader(string name){
    //className_ = name.c_str();   //same result with .data()
    className_ = name.data();