所谓在谷歌试验基地的方法(Base method called in Google Test)

2019-10-18 04:42发布

我想C ++编写一个二叉树的实现,我使用谷歌测试测试它。 为了测试中序遍历我是子类的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;
}

Answer 1:

问题是在你的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的析构函数是虚拟的。 (参见有效C ++项#7​​)



文章来源: Base method called in Google Test