为了给出我遇到的问题的简单示例,请考虑创建链接的类(如链中)。除根链接外,每个链接都有一个父链接。根链接的父链接为null。
#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;
}
在单元测试我的代码时,我创建了一个辅助类,它定义了对测试有用的函数。在HelperClass.hpp中有一个静态方法,它创建一个指向链接的共享指针并返回原始指针。请记住,此辅助函数仅用于重现问题。我明白这种方法有点无用。
#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
中创建指向链接的指针的行为正在改变parentLink
的{{1}}。请注意,如果我只是在堆栈上实例化一个新的链接,rootLink
的{{1}}仍然是parentLink
。我在这里错过了什么?非常感谢您的帮助!
答案 0 :(得分:1)
createRootLink
返回一个悬空指针。
Link* Link::createRootLink(const std::string &linkName)
{
std::unique_ptr<Link> rootLink(new Link(linkName));
return rootLink.get();
}
unique_ptr
在超出范围时删除其对象,该范围位于createRootLink
函数的末尾。这样可以重用内存,或者各种其他未定义的行为。