首页 > 解决方案 > 当函数超出范围时,成员变量如何在本地对象被删除后存活

问题描述

我有 3 个类:基础、容器和实体:

我想填充类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;
}

标签: c++pointersreference

解决方案


推荐阅读