c++ - 当函数超出范围时,成员变量如何在本地对象被删除后存活
问题描述
我有 3 个类:基础、容器和实体:
类 Base 有一个字符串成员变量
类容器是 char * 缓冲区的包装器
Class Entity 有一个静态函数,它接受一个容器作为参数,并使用它的缓冲区来填充它的静态成员变量,称为 value
我想填充类Entity的成员变量如下:
void setLocalCopy(Entity &e, const Base & b) {
char buffer[2048] = {};
copy(b.getString().begin(), b.getString().end(), buffer);
Container c(buffer);
Entity::setValue(c);
}
在 setLocalCopy 中,我们通过将类 Base 的字符串复制到缓冲区中来初始化缓冲区。然后我们用缓冲区实例化一个对象容器并设置实体的值。这里的问题是 Container 是 setLocalCopy 的 LOCAL VARIABLE。当 setLocalCopy 超出范围时,容器对象将被销毁。
为了解决这个问题,我编写了 setReferenceToBase 函数:
void setReferenceToBase(Entity &e, const Base & b) {
char *buffer = const_cast<char*>(b.getString().c_str());
Container c(buffer);
Entity::setValue(c);
}
在 setReferenceToBase 中,我创建了一个指向 Base 类的 _str 成员变量的指针。现在,由于 Base 是在 main 中动态创建的,因此它将一直存在到程序结束或直到我将其删除。
我不明白的部分缓冲区的价值是如何生存的?容器对象应该被销毁,我们离开 setReferenceToBase。是因为它是指向动态创建的类的成员变量的指针吗?
除此之外,valgrind 没有显示任何内存泄漏。
源代码示例
#include <iostream>
#include <string>
class Base {
public:
Base(const std::string & str):_str(str) {}
const std::string &getString() const {
return _str;
}
private:
std::string _str;
};
class Container {
public:
Container(char *buffer):_buffer(buffer) {}
char *getBuffer() {
return _buffer;
}
private:
char * _buffer;
};
class Entity {
public:
Entity() {}
static void setValue(Container _c) {
_value = _c.getBuffer();
}
static const std::string & value() {
return _value;
}
private:
static std::string _value;
};
std::string Entity::_value = {};
void setLocalCopy(Entity &e, const Base & b) {
char buffer[2048] = {};
copy(b.getString().begin(), b.getString().end(), buffer);
Container c(buffer);
Entity::setValue(c);
}
void setReferenceToBase(Entity &e, const Base & b) {
char *buffer = const_cast<char*>(b.getString().c_str());
Container c(buffer);
Entity::setValue(c);
}
int main()
{
Base *b = new Base("base");
Entity e;
setLocalCopy(e,*b);
std::cout << Entity::value() << std::endl;
setReferenceToBase(e,*b);
std::cout << Entity::value() << std::endl; //OK but I don't know why
delete b;
return 0;
}
解决方案
推荐阅读
- docker - 为什么 (mariadb) mysqldump 用 NULL 替换一些 varchar?
- scala - 为什么 Scala 中的高阶统一被认为是部分的?
- node.js - Node.js 复选框控制器
- asp.net - ListView 图像中的 ASP.NET Ajax ToggleButton 仅在第一行可见
- excel - Excel 公式,用于将位于列中字符串的每个匹配项正下方的所有值相加
- flutter - Flutter_Tex 不显示任何文本
- windows - Cmake找不到msys2的luajit包(windows)
- linux - 从文件系统隐藏文件而不是从mysql?
- c# - 在 Blazor 中使用带有“onchange”事件的通用 TItem
- pandas - Pandsas pivot_table 的“没有要聚合的数字类型”