Временная проблема в C ++ - PullRequest
       1

Временная проблема в C ++

0 голосов
/ 12 апреля 2011

У меня есть этот фрагмент кода, который печатает содержимое каталога с помощью Boost.Filesystem:

class Shell {
private:
    const string& command;
    const path& firstPath;
    const path& secondPath;
public:
    // constructor
    Shell(const string& _command, const path& _firstPath, const path& _secondPath = path()): command(_command), firstPath(_firstPath), secondPath(_secondPath) {}

    //destructor
    ~Shell() {}

    //execute commands
    void executeCommand()
    {
        if(command.compare("ls"))
        {
            ls();
        }
    }

    void ls()
    {
        if(exists(firstPath)) 
        {
            vector<path> vecPath;

            copy(directory_iterator(firstPath), directory_iterator(), back_inserter(vecPath));
            sort(vecPath.begin(), vecPath.end());
            for(vector<path>::iterator it = vecPath.begin(); it != vecPath.end(); ++it)
            {
                cout << *it << endl;
            }
        }
    }
};


int main(int argc, char** argv) 
{
    path Path = "c:\\workspace";
    Shell shell("ls", Path); // GOOD
    // Shell shell("ls", "c:\\workspace");  BAD creates temporary !!
    shell.executeCommand();
}

Если я отправлю свой второй аргумент direclty как const char * Я знаю, что он создаст временныйи мой аргумент конструктора будет виден только в конструкторе, а затем потерян из-за ссылки на временный.
Мой вопрос: почему то же самое не происходит с первым аргументом, строкой, потому что я посылаю ему такжекак const char * напрямую, но значение не теряется вне конструктора?

Ответы [ 3 ]

5 голосов
/ 12 апреля 2011
Shell shell("ls", Path); // BAD - just happens to work as you expected.

Неопределенное поведение - может случиться все, что угодно, в том числе действовать так, как вы ожидаете. Память, выделенная временным, просто не была перезаписана в вашем случае.

2 голосов
/ 12 апреля 2011
std::string *ref;

{ 
    std::string tmp("temp");
    ref = &ref;  // risky, need to keep lifetime of tmp in mind

    const char* const rawptr = ref->c_str(); // equivalent to tmp.c_str()

    tmp = "altered"; // *ref also modified, rawptr completely invalid
}
// *ref _and_ rawptr completely invalid.
1 голос
/ 12 апреля 2011

Есть ли конкретная причина, по которой вы храните ссылки вместо копий? Изменив свой класс с

class Shell {
private:
    const string& command;
    const path& firstPath;
    const path& secondPath;
...

до

class Shell {
private:
    const string command;
    const path firstPath;
    const path secondPath;
...

Вы можете избежать многих проблем, и оба случая будут правильными. Почему это так, вы можете увидеть в ответе sehe

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...