静态方法中的对象创建正在更改其他静态对象的私有成员变量

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 的指针的行为不知何故改变了 rootLinkparentLink。请注意,如果我只是在堆栈上实例化一个新的 Link,rootLinkparentLink 将保持 nullptr 应有的状态。我在这里错过了什么?非常感谢您的帮助!

createRootLink returns 悬空指针。

Link* Link::createRootLink(const std::string &linkName)
{
    std::unique_ptr<Link> rootLink(new Link(linkName));
    return rootLink.get();
}

unique_ptr 在超出范围时删除它的对象,这是在 createRootLink 函数的末尾。这样内存就可以被重用,或者各种其他未定义的行为。