静态方法中的对象创建正在更改其他静态对象的私有成员变量
Object creation in static method is changing private member variables of other static object
举一个我遇到的问题的简单例子,考虑一个 class 创建一个 link(就像在一个链中)。除了根 link 之外,每个 link 都有一个父 link。根 link 的父 link 为空。
#ifndef LINK_HPP
#define LINK_HPP
#include <memory>
#include <string>
//Link.hpp
class Link
{
public:
Link(const std::string &linkName, const Link *parentLink);
Link(const std::string &linkName);
const Link* getParentLink();
~Link();
static Link* createRootLink(const std::string &linkName);
static Link* getRootLink();
private:
std::string linkName;
const Link *parentLink;
};
#endif
#include "Link.hpp"
Link* Link::createRootLink(const std::string &linkName)
{
std::unique_ptr<Link> rootLink(new Link(linkName));
return rootLink.get();
}
Link::Link(const std::string &linkName)
{
this->linkName = linkName;
this->parentLink = nullptr;
}
Link::Link(const std::string &linkName, const Link* parentLink)
{
this->linkName = linkName;
this->parentLink = parentLink;
}
Link::~Link()
{
}
const Link* Link::getParentLink()
{
return this->parentLink;
}
在对我的代码进行单元测试时,我创建了一个助手 class,它定义了对测试有用的函数。在 HelperClass.hpp 中有一个静态方法创建一个指向 link 和 returns 原始指针的共享指针。请记住,此辅助函数只是为了重现问题。我知道这个方法有点没用。
#include "Link.hpp"
class HelperClass
{
public:
static Link* createALink(const std::string &linkName, Link* parentLink)
{
std::shared_ptr<Link> link(new Link(linkName, parentLink));
return link.get();
}
};
好了,现在进行实际测试,找出问题所在。
#include "gtest/gtest.h"
#include "Link.hpp"
#include "HelperClass.hpp"
class ReferenceFrameTest : public ::testing::Test
{
protected:
virtual void SetUp()
{
}
virtual void TearDown()
{
}
Link* rootLink = Link::createRootLink("root");
// Why does this call right here change the parentLink of rootLink!!
Link* link1 = HelperClass::createALink("link1", rootLink);
private:
};
TEST_F(ReferenceFrameTest, testRootLinkHasNullParent)
{
// the parent link of rootLink should be nullptr or 0
// this currently outputs 0x264f960
std::cout << rootLink->getParentLink() << std::endl;
// This fails if I create the Link* from HelperClass.hpp
ASSERT_FALSE(rootLink->getParentLink());
}
在 HelperClass
中创建指向 Link 的指针的行为不知何故改变了 rootLink
的 parentLink
。请注意,如果我只是在堆栈上实例化一个新的 Link,rootLink
的 parentLink
将保持 nullptr
应有的状态。我在这里错过了什么?非常感谢您的帮助!
createRootLink
returns 悬空指针。
Link* Link::createRootLink(const std::string &linkName)
{
std::unique_ptr<Link> rootLink(new Link(linkName));
return rootLink.get();
}
unique_ptr
在超出范围时删除它的对象,这是在 createRootLink
函数的末尾。这样内存就可以被重用,或者各种其他未定义的行为。
举一个我遇到的问题的简单例子,考虑一个 class 创建一个 link(就像在一个链中)。除了根 link 之外,每个 link 都有一个父 link。根 link 的父 link 为空。
#ifndef LINK_HPP
#define LINK_HPP
#include <memory>
#include <string>
//Link.hpp
class Link
{
public:
Link(const std::string &linkName, const Link *parentLink);
Link(const std::string &linkName);
const Link* getParentLink();
~Link();
static Link* createRootLink(const std::string &linkName);
static Link* getRootLink();
private:
std::string linkName;
const Link *parentLink;
};
#endif
#include "Link.hpp"
Link* Link::createRootLink(const std::string &linkName)
{
std::unique_ptr<Link> rootLink(new Link(linkName));
return rootLink.get();
}
Link::Link(const std::string &linkName)
{
this->linkName = linkName;
this->parentLink = nullptr;
}
Link::Link(const std::string &linkName, const Link* parentLink)
{
this->linkName = linkName;
this->parentLink = parentLink;
}
Link::~Link()
{
}
const Link* Link::getParentLink()
{
return this->parentLink;
}
在对我的代码进行单元测试时,我创建了一个助手 class,它定义了对测试有用的函数。在 HelperClass.hpp 中有一个静态方法创建一个指向 link 和 returns 原始指针的共享指针。请记住,此辅助函数只是为了重现问题。我知道这个方法有点没用。
#include "Link.hpp"
class HelperClass
{
public:
static Link* createALink(const std::string &linkName, Link* parentLink)
{
std::shared_ptr<Link> link(new Link(linkName, parentLink));
return link.get();
}
};
好了,现在进行实际测试,找出问题所在。
#include "gtest/gtest.h"
#include "Link.hpp"
#include "HelperClass.hpp"
class ReferenceFrameTest : public ::testing::Test
{
protected:
virtual void SetUp()
{
}
virtual void TearDown()
{
}
Link* rootLink = Link::createRootLink("root");
// Why does this call right here change the parentLink of rootLink!!
Link* link1 = HelperClass::createALink("link1", rootLink);
private:
};
TEST_F(ReferenceFrameTest, testRootLinkHasNullParent)
{
// the parent link of rootLink should be nullptr or 0
// this currently outputs 0x264f960
std::cout << rootLink->getParentLink() << std::endl;
// This fails if I create the Link* from HelperClass.hpp
ASSERT_FALSE(rootLink->getParentLink());
}
在 HelperClass
中创建指向 Link 的指针的行为不知何故改变了 rootLink
的 parentLink
。请注意,如果我只是在堆栈上实例化一个新的 Link,rootLink
的 parentLink
将保持 nullptr
应有的状态。我在这里错过了什么?非常感谢您的帮助!
createRootLink
returns 悬空指针。
Link* Link::createRootLink(const std::string &linkName)
{
std::unique_ptr<Link> rootLink(new Link(linkName));
return rootLink.get();
}
unique_ptr
在超出范围时删除它的对象,这是在 createRootLink
函数的末尾。这样内存就可以被重用,或者各种其他未定义的行为。