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

时间:2015-08-29 23:07:30

标签: c++ oop pointers static-methods

为了给出我遇到的问题的简单示例,请考虑创建链接的类(如链中)。除根链接外,每个链接都有一个父链接。根链接的父链接为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。我在这里错过了什么?非常感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

createRootLink返回一个悬空指针。

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

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