当我尝试通过共享指针访问类的成员时,我遇到了一个问题。
该程序运行良好并提供预期的输出:"Name: Michel"。但是当我评论标记为的行时COMMENT_THIS_LINE,它给出了一些垃圾值而不是Michel. 任何人都可以解释这种行为,以及如何在没有标记线的情况下获得正确的输出?
class TestShared{
public:
TestShared(std::string name);
std::string getName(void);
private:
std::string m_name;
};
class Another{
public:
const char *name;
};
TestShared::TestShared(std::string name) : m_name(name)
{
}
std::string TestShared::getName(void)
{
return m_name;
}
std::shared_ptr<TestShared> allocate_ts()
{
char p[] = "Michel";
return std::make_shared<TestShared>(p);
}
Another GetAnother(std::shared_ptr<TestShared> ts)
{
Another an;
std::string a = ts->getName(); //////////COMMENT_THIS_LINE
an.name = ts->getName().c_str();
return an;
}
int main()
{
std::shared_ptr<TestShared> ts = allocate_ts();
Another an = GetAnother(ts);
printf("Name: %s\n", an.name);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
重要的一点是:
std::string TestShared::getName(void)
{
return m_name;
}
Run Code Online (Sandbox Code Playgroud)
和这个:
Another an;
an.name = ts->getName().c_str(); // (*)
return an;
Run Code Online (Sandbox Code Playgroud)
getName()返回私有字符串的副本。c_str()返回一个指向该临时的内部字符数组的指针。an.name存储该指针,该指针已经悬空在;in 处(*)。
您需要复制字符串,或者char*在您真正需要string.
返回对成员m_namefrom的引用getName()也可以解决当前的问题,但是如果您想an.name存储一个字符串,您实际上应该存储一个字符串,而不仅仅是指向其他字符串的内部缓冲区的指针。
您的代码具有未定义的行为,因为当时您通过printf("Name: %s\n", an.name);指针打印字符串不再有效。将string它指向的是早已不复存在。未定义的行为可能会产生奇怪的效果,例如添加一条看似无关的行来改变行为。当存在额外的代码行时,不要被产生预期输出的代码误导。这只是一个副作用,您的代码是错误的,即使它看起来有效。
| 归档时间: |
|
| 查看次数: |
66 次 |
| 最近记录: |