微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

通过共享指针访问类成员

如何解决通过共享指针访问类成员

当我尝试通过共享指针访问类的成员时,我遇到了一个问题。

程序运行良好并给出了预期的输出"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;
}

解决方法

重要的一点是:

std::string TestShared::getName(void)
{
    return m_name;
}

还有这个:

Another an;
an.name = ts->getName().c_str();   // (*)
return an;

getName() 返回私有字符串的副本。 c_str() 返回一个指向该临时文件的内部字符数组的指针。 an.name 存储该指针,该指针已经悬挂在 ; 中的 (*) 处。

您需要复制字符串,或者当您真正需要 char* 时,不要使用 string 指针。

m_name 返回对成员 getName() 的引用也可以解决当前的问题,但是如果您希望 an.name 存储一个字符串,您实际上应该存储一个字符串,而不仅仅是指向其他字符串的内部缓冲区的指针。

您的代码有未定义的行为,因为当您通过 printf("Name: %s\n",an.name); 打印字符串时,指针不再有效。它指向的 string 早已不复存在。未定义的行为可能会产生奇怪的效果,例如添加一条看似无关的行来改变行为。当存在额外的代码行时,不要被产生预期输出的代码误导。这只是一个副作用,您的代码是错误的,即使它看起来有效。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?