繁体   English   中英

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

[英]converting std::string to const char * and function calls

我的类中有多个需要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()] = '\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();
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM