当函数超出范围时,删除本地对象后成员变量如何生存

时间:2019-01-23 19:39:26

标签: c++ pointers reference

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

  • Class Base具有一个字符串成员变量

  • 类容器是char *缓冲区的包装器

  • 类实体具有一个静态函数,该函数将容器作为参数并使用其缓冲区填充其静态成员变量(称为值)

我要按如下所示填充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,并设置Entity的值。这里的问题是Container是setLocalCopy的局部变量。当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;
}

0 个答案:

没有答案