關於物件的「==」運算子與提昇UX。

這不是要教你怎麼覆寫==運算子,讓物件的==得到適當的定義。
而是要教你,如何告訴使用者,哪一個沒有比對結果。

示範準備程式碼
#include <vector>
#include <iterator>
#include <iostream>

class tObj
{
    int m_condition[3];
public:
    void setCondition(const int& Value1, const int& Value2, const int& Value3)
    {
        m_condition[0] = Value1;
        m_condition[1] = Value2;
        m_condition[2] = Value3;
    }
    const int getCondition(int index) const
    {
        return m_condition[index];
    }
    bool operator==(const tObj& obj) const
    {
        if ( (m_condition[0] == obj.m_condition[0]) && 
             (m_condition[1] == obj.m_condition[1]) && 
             (m_condition[2] == obj.m_condition[2]) )
            return true;
        else
            return false;
    }
};

void InitDB(tObj* o)
{
    (o+0)->setCondition(4, 6, 8);
    (o+1)->setCondition(2, 6, 6);
    (o+2)->setCondition(2, 6, 6);
    (o+3)->setCondition(2, 6, 8);
    (o+4)->setCondition(2, 4, 8);
    (o+5)->setCondition(2, 4, 8);
    (o+6)->setCondition(2, 4, 8);
    (o+7)->setCondition(2, 4, 8);
    (o+8)->setCondition(2, 4, 8);
    (o+9)->setCondition(2, 4, 8);
}

void DBtoVector(tObj* o, std::vector<tObj>& vo)
{
    for (int i = 0; i < 10; ++i)
        vo.push_back(*(o+i));
}

void displayMatch(std::vector<tObj> const& matchSample)
{
    for (std::vector<tObj>::const_iterator ims  = matchSample.begin();
                                           ims != matchSample.end(); ++ims)
        std::cout << ims->getCondition(0) << ", " 
                  << ims->getCondition(1) << ", " 
                  << ims->getCondition(2) << ", " << std::endl;
}

void isMatch(const tObj& x, std::vector<tObj>& vo)
{
    std::vector<tObj> matchSample;
    for (std::vector<tObj>::iterator it = vo.begin(); it != vo.end(); ++it)
        if (*it == x)  matchSample.push_back(*it);
    vo.clear();
    vo = matchSample;
}

int main(int argc, char const *argv[])
{
    tObj o[10];           InitDB(o);
    std::vector<tObj> vo; DBtoVector(o, vo);
    tObj x;               x.setCondition(2, 4, 8);  //sample

    isMatch(x, vo);    
    displayMatch(vo);

    return 0;
}

一開始,C++的書都會教我們,比對資料這件事覆寫operator==()然後,用vector + iterator + for就可以找出來想要的了!。
但是,為了使用者!你必須告訴他,如果比對資料輸入錯誤,那麼,又該怎麼寫,才可以告訴使用者「你的第幾個值寫錯了」呢?

第一件事,就是刪掉operator==()先。真的!

新增這一段程式碼
const bool partsMatch(const int& index, std::vector<tObj>& vo, const tObj& x)
{
    std::vector<tObj> matchSample;
    for (std::vector<tObj>::iterator it = vo.begin(); it != vo.end(); ++it)
        if (it->getCondition(index) == x.getCondition(index))
            matchSample.push_back(*it);

    vo.clear();
    vo = matchSample;
    return (matchSample.size()) ? true : false;
}
修改這一段程式碼,將回傳值改成字串
std::string isMatch(const tObj& x, std::vector<tObj>& vo)
{
    if (!partsMatch(0, vo, x))
        return "條件1 無符合項目";
    else if (!partsMatch(1, vo, x))
        return "條件2 無符合項目";
    else if (!partsMatch(2, vo, x))
        return "條件3 無符合項目";
    else
        return "完全符合";
}
主程式修改一下
int main(int argc, char const *argv[])
{
    tObj o[10];           InitDB(o);
    std::vector<tObj> vo; DBtoVector(o, vo);
    tObj x;               x.setCondition(2, 6, 1);  //sample

    std::cout << isMatch(x, vo) << std::endl;
    displayMatch(vo);

    return 0;
}
最後變成這樣(全部的程式碼)
#include <vector>
#include <iterator>
#include <iostream>
#include <string>

class tObj
{
    int m_condition[3];
public:
    void setCondition(const int& Value1, const int& Value2, const int& Value3)
    {
        m_condition[0] = Value1;
        m_condition[1] = Value2;
        m_condition[2] = Value3;
    }
    const int getCondition(int index) const
    {
        return m_condition[index];
    }
};

void InitDB(tObj* o)
{
    (o+0)->setCondition(4, 6, 8);
    (o+1)->setCondition(2, 6, 6);
    (o+2)->setCondition(2, 6, 6);
    (o+3)->setCondition(2, 6, 8);
    (o+4)->setCondition(2, 4, 8);
    (o+5)->setCondition(2, 4, 8);
    (o+6)->setCondition(2, 4, 8);
    (o+7)->setCondition(2, 4, 8);
    (o+8)->setCondition(2, 4, 8);
    (o+9)->setCondition(2, 4, 8);
}

void DBtoVector(tObj* o, std::vector<tObj>& vo)
{
    for (int i = 0; i < 10; ++i)
        vo.push_back(*(o+i));
}

void displayMatch(std::vector<tObj> const& matchSample)
{
    for (std::vector<tObj>::const_iterator ims  = matchSample.begin();
                                           ims != matchSample.end(); ++ims)
        std::cout << ims->getCondition(0) << ", " 
                  << ims->getCondition(1) << ", " 
                  << ims->getCondition(2) << ", " << std::endl;
}

const bool partsMatch(const int& index, std::vector<tObj>& vo, const tObj& x)
{
    std::vector<tObj> matchSample;
    for (std::vector<tObj>::iterator it = vo.begin(); it != vo.end(); ++it)
        if (it->getCondition(index) == x.getCondition(index))
            matchSample.push_back(*it);

    vo.clear();
    vo = matchSample;
    return (matchSample.size()) ? true : false;
}

std::string isMatch(const tObj& x, std::vector<tObj>& vo)
{
    if (!partsMatch(0, vo, x))
        return "條件1 無符合項目";
    else if (!partsMatch(1, vo, x))
        return "條件2 無符合項目";
    else if (!partsMatch(2, vo, x))
        return "條件3 無符合項目";
    else
        return "完全符合";
}

int main(int argc, char const *argv[])
{
    tObj o[10];           InitDB(o);
    std::vector<tObj> vo; DBtoVector(o, vo);
    tObj x;               x.setCondition(2, 6, 1);  //sample

    std::cout << isMatch(x, vo) << std::endl;
    displayMatch(vo);

    return 0;
}
也許不是完全美的做法,但是,還不賴。

沒有留言:

張貼留言

(什麼是留言欄訊息?)