c++ - Google Test 中调用的基本方法

标签 c++ googletest

我正在尝试用 C++ 编写二叉树实现,并使用 Google Test 对其进行测试。为了测试中序遍历,我对 BTree 类进行了子类化,这样我就可以覆盖 visit() 方法,这样我就可以输出到一个字符串到控制台。问题是我想使用现有的逻辑将新节点插入到树中,它插入的是基类而不是派生类,即使我将派生对象的指针传递给 insert()方法。有没有办法让它为所有节点插入派生类?

这是测试用例:

TEST_F(BTreeTestSuite, inOrder)
{
    class InOrderTest : public BTree
    {
    public:
        InOrderTest(int data) throw(int) : BTree(data), itsVisitString() {};
        virtual ~InOrderTest() {};
        std::string visitString(void) const { return itsVisitString; }
        virtual void visit()
        {
            std::ostringstream oss;
            oss << itsData;
            itsVisitString += oss.str();
            std::cerr << "vs1: " << itsVisitString << '|' << std::endl;
            itsVisitString += " ";
            std::cerr << "vs2: " << itsVisitString << '|' << std::endl;
        }
    private:
        std::string itsVisitString;
    };
    InOrderTest iot(20);
    iot.insert(new InOrderTest(30));
    iot.insert(new InOrderTest(15));
    iot.insert(new InOrderTest(10));
    iot.inOrder();
    EXPECT_STREQ("10 15 20 30 ", iot.visitString().c_str());
}

下面是基类的相关部分:

class BTree
{
public:
    BTree(int data) throw();        // constructor(s)
    ~BTree() throw();               // destructor

    virtual void insert(BTree *node);
    unsigned count() const;
    void inOrder();
    virtual void visit();

    int   data() const throw() { return itsData; };
    BTree *left() const throw() { return itsLeft; };
    BTree *right() const throw() { return itsRight; };

protected:
    int     itsData;
private:
    // Don't allow creation of BTree without data
    BTree() throw();        // constructor(s)
    BTree   *itsLeft;
    BTree   *itsRight;
};
...
BTree::BTree(int data) throw() : itsData(data)
{
    itsLeft = itsRight = 0;
}

void BTree::insert(BTree *node)
{
    if (node->itsData < itsData)
    {
        std::cerr << "Inserting data on the left\n";
        if (itsLeft)
        {
            itsLeft->insert(node);
        }
        else
        {
            itsLeft = new BTree(node->itsData);
        }

    }

    if (node->itsData > itsData)
    {
        std::cerr << "Inserting data on the right\n";
        if (itsRight)
        {
            itsRight->insert(node);
        }
        else
        {
            itsRight = new BTree(node->itsData);
        }
    }

    /* Drop value if it already exists in tree. */
}

void BTree::inOrder()
{
    if (itsLeft) itsLeft->inOrder();
    visit();
    if (itsRight) itsRight->inOrder();
}

void BTree::visit()
{
    cout << "base-visit: " << itsData << endl;
}

最佳答案

问题出在您的 BTree::insert 方法中。即使它获得了 InOrderTest *,您也正在从这两行中创建 BTree 的实例:

void BTree::insert(BTree *node)
{
  // logic checks...
  itsLeft = new BTree(node->itsData);
  // more logic checks...
  itsRight = new BTree(node->itsData);
  //...
}

您可以采用两种方法来解决此问题。您可以只使用传入的节点而不是构造新对象。在这种情况下,您的根节点拥有其子节点的所有权,并应负责适本地解除分配它们。由于您的单元测试正在执行 new InOrderTest 而没有匹配的 delete,因此这种方法可行。

第二种方法是创建一个虚拟的clone 方法并让您的派生类处理它自己的创建。

class BTree
{
  // BTree stuff
public:
  virtual BTree* BTree::clone() const;
  // more stuff
};

class InOrderTest : public BTree
{
public:
  InOrderTest* clone() const { return new InOrderTest(*this); }
};

此外,如果您希望使用 BTree 的客户端代码从它派生,则将 BTree::~BTree 析构函数设为虚拟。 (参见 Effective C++ item#7)

关于c++ - Google Test 中调用的基本方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16727037/

相关文章:

c++ - 我可以将复制构造函数设为私有(private)并仍然使用默认实现吗

c++ - GCC ICE——替代函数语法、可变参数模板和元组

c++ - 如何编写在函数执行过程中收集垃圾的测试用例?

c++ - Qt5.0.0 ITK4.12 VTK 7.1.1 Visual Studio 2010 x64

c++ - 将带有模板参数的方法传递给宏

c++ - 使用 gtest 进行 Arduino 单元测试

c++ - Google 测试中的 EXPECT_NO_DEATH()

c++ - COM 的跨平台替代品

C++/GoogleTest - 如何测试被测类的成员变量

c++ - 在 Xcode 中新建一个 "Shell Tool"目标,用于 Google Test