Google测试中调用的基本方法 [英] Base method called in Google Test

查看:76
本文介绍了Google测试中调用的基本方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to write a binary tree implementation in C++ and I'm testing it using Google Test. In order to test the in-order traversal I am sub-classing the BTree class so that I can override the visit() method so that I can output to a string instead of to the console. The problem is that I want to use the existing logic to insert new nodes to the tree and it's inserting the base class instead of the derived class even though I am passing a pointer to a derived object to the insert() method. Is there a way to get it to insert the derived class for all the nodes?

这是测试用例:

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());
}

以下是基类的相关部分:

Here's the relevant portions of the base class:

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的实例:

The problem is in your BTree::insert method. Even though it's getting a InOrderTest * you're creating an instance of BTree from that on these two lines:

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

您可以采用两种方法来解决此问题.您可以只使用传入的节点,而不必构造新的对象.在这种情况下,您的根节点将拥有其子节点的所有权,并应注意适当时对其进行分配.由于单元测试正在执行new InOrderTest而没有匹配的delete,因此这种方法可以工作.

There are two approaches you can take to solve this. You can just use the node passed in instead of constructing a new object. In this case, your root node assumes ownership of its children and should take care of deallocating them as appropriate. Since your unittest is doing new InOrderTest with no matching delete anyway, this approach can work.

第二种方法是创建一个虚拟的clone方法,并让您的派生类处理自身的创建.

The second way is to create a virtual clone method and have your derive classes handle its own creation of itself.

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析构函数设为虚拟. (请参阅有效的C ++项目#7)

Also, if you expect client code using BTree to derive from it then make BTree::~BTree destructor virtual. (See Effective C++ item#7)

这篇关于Google测试中调用的基本方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆