真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

典型問題分析(十五)-創(chuàng)新互聯(lián)

       在經(jīng)過一段時間的編寫,我們的數(shù)據(jù)結(jié)構(gòu)庫已經(jīng)有了一定的規(guī)模。那么我們之前編寫的代碼就沒有一點 bug 嗎?之前每個代碼都是經(jīng)過測試了的,因此闊能是沒有 bug 的,但是我們還是來對它進行分析,看看究竟是否一點 bug 都沒有呢。

創(chuàng)新互聯(lián)是一家專注于成都網(wǎng)站建設(shè)、成都網(wǎng)站制作與策劃設(shè)計,遷西網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)10余年,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:遷西等地區(qū)。遷西做網(wǎng)站價格咨詢:028-86922220

       測試 1 :創(chuàng)建異常對象時的空指針問題,如下

典型問題分析(十五)

main.cpp 如下

#include 
#include "Exception.h"

using namespace std;
using namespace DTLib;

int main()
{
    try
    {
        NullPointerException npe;

        cout << "throw" << endl;

        throw npe;
    }
    catch(const Exception& e)
    {
        cout << "catch" << endl;
    }

    return 0;
}

       我們來看看編譯結(jié)果

典型問題分析(十五)

       我們看到編譯運行時正常結(jié)束的,并沒有出錯。那么這是否就說明我們之前所編寫的代碼一點 bug 也沒有呢?我們來看看之前的 Exception 類族是怎樣實現(xiàn)的,它調(diào)用的是 strdup 函數(shù)實現(xiàn)的。我們在網(wǎng)上搜下 strdup 函數(shù)是怎樣實現(xiàn)的,它的源碼如下

典型問題分析(十五)

       我們看到它并沒有做指針 s 為空的判斷,因此我們直接使用這個函數(shù)還是有問題的。我們要在 message 賦值這塊使用下三目運算符來進行判斷,代碼如下

void Exception::init(const char* message, const char* file, int line)
{
    m_message = (message ? strdup(message) : NULL);

    if( file != NULL )
    {
        char s1[16] = {0};

        itoa(line, s1, 10);

        m_location = static_cast(malloc(strlen(file) + strlen(s1) + 2));
        m_location = strcpy(m_location, file);
        m_location = strcat(m_location, ":");
        m_location = strcat(m_location, s1);
    }
    else
    {
        m_location = NULL;
    }
}

       這樣的話,代碼就足夠安全了。

       測試 2 :LinkList 中的數(shù)據(jù)元素刪除

main.cpp 如下

#include 
#include "LinkList.h"

using namespace std;
using namespace DTLib;

class Test : public Object
{
    int m_id;
public:
    Test(int id = 0)
    {
        m_id = id;
    }

    ~Test()
    {
        if( m_id == 1 )
        {
            throw m_id;
        }
    }
};

int main()
{
    LinkList list;
    Test t0(0), t1(1), t2(2);

    try
    {
        list.insert(t0);
        list.insert(t1);
        list.insert(t2);

        list.remove(1);
    }
    catch(int e)
    {
        cout << e << endl;
        cout << list.length() << endl;
    }

    return 0;
}

       我們在 QT 中編譯運行的時候直接崩潰了,因為 Test 類在析構(gòu)時拋出異常了。在 VS 上運行時可以得到一丁點的結(jié)果,打印出的結(jié)果是鏈表的長度為 3。在銷毀 t1 對象之后,結(jié)果還是為 3,這個結(jié)果就有點問題了。我們來看看 LinkList 的 remove 操作是怎樣實現(xiàn)的,它是在 destroy 之后才進行 m_length-- 的。我們應(yīng)該在 destroy 之前進行 m_length--才行。那么 remove 操作有問題,clear 操作肯定也有問題了。我們應(yīng)該在 destroy 之前進行 m_length-- 的操作,而不是在最后將它賦值為 0。

        測試 3 :LinkList 中遍歷操作與刪除操作的混合使用

main.cpp 如下

#include 
#include "LinkList.h"

using namespace std;
using namespace DTLib;

int main()
{
    LinkList list;

    for(int i=0; i<5; i++)
    {
        list.insert(i);
    }

    for(list.move(0); !list.end(); list.next())
    {
        if( list.current() == 3 )
        {
            list.remove(list.find(list.current()));
            
            cout << list.current() << endl;
        }
    }

    for(int i=0; i

       我們來編譯運行,看看結(jié)果

典型問題分析(十五)

       結(jié)果是正確的,那么上面在查找數(shù)值為 3 的元素,查找成功之后刪除。那么刪除完之后他的 current 值為多少呢?我們看到結(jié)果是一個隨機數(shù)。那么問題來了,我們在刪除之后,理論上看到的數(shù)據(jù)元素應(yīng)該是它的下一個數(shù)字 4 啊。這是就需要修改 remove 函數(shù)了。我們在 remove 函數(shù)中添加一個判斷,如果它是指向即將要被刪除的元素,那么就將它指向 toDel->next。具體改動如下

bool remove(int i)
{
    bool ret = ((0 <= i) && (i < m_length));

    if( ret )
    {
        Node* current = position(i);
        Node* toDel = current->next;

        if( m_current == toDel )
        {
            m_current = toDel->next;
        }

        current->next = toDel->next;

        m_length--;

        destroy(toDel);
    }

    return ret;
}

       我們再來看看編譯結(jié)果

典型問題分析(十五)

       那么此時這個 bug 就已經(jīng)解決了。

       測試 4 :StaticLinkList 中數(shù)據(jù)元素刪除時的效率問題

main.cpp 如下

#include 
#include "StaticLinkList.h"

using namespace std;
using namespace DTLib;

int main()
{
    StaticLinkList list;

    for(int i=0; i<5; i++)
    {
        list.insert(i);
    }

    list.remove(3);

    for(int i=0; i

       我們來看看編譯結(jié)果

典型問題分析(十五)

       結(jié)果自然是沒錯的,我們再來仔細看看 StaticLinkList 類的 destroy 函數(shù)。在歸還空間之后,我們應(yīng)該直接跳出循環(huán),這樣效率會高一點。

       測試 5 :StaticLinkList 是否需要提供析構(gòu)函數(shù)?

main.cpp 如下

#include 
#include "StaticLinkList.h"

using namespace std;
using namespace DTLib;

int main()
{
    StaticLinkList list;

    for(int i=0; i<5; i++)
    {
        list.insert(i);
    }

    for(int i=0; i

       我們在 LinkList 類中是提供了析構(gòu)函數(shù)的,并且這個析構(gòu)函數(shù)是虛函數(shù)。我們根據(jù)之前的知識,雖然父類 LinkList 有析構(gòu)函數(shù)的實現(xiàn),但是這個析構(gòu)函數(shù)不會發(fā)生多態(tài)的,所以說在 LinkList 中調(diào)用的 clear 函數(shù)是 LinkList 中的 clear 函數(shù),在 StaticLinkList 中的 clear 函數(shù)調(diào)用的也是 LinkList 中的 clear 函數(shù)。但是在 clear 函數(shù)中調(diào)用的是 destroy 函數(shù),所以兩個類調(diào)用的 destroy 函數(shù)都是 LinkList 類中的 destroy 函數(shù)。我們在 LinkList 和 StaticLinkList 中的 create 和 destroy 函數(shù)中都打上斷點,然后進行斷點調(diào)試,看看結(jié)果

典型問題分析(十五)

       我們看到在進行 create 的時候,因為類對象是 StaticLinkList 類型的,所以它會去按照 StaticLinkList 的方式來進行 create,再來看看 destroy 時,進行的是哪個類函數(shù)的實現(xiàn)

典型問題分析(十五)

       我們看到在進行 destroy 時進行的是 LinkList 方式,這時便出現(xiàn)問題了。此時 delete 操作有可能不是進行的是堆空間上的操作,那么程序沒直接崩潰時因為這個程序太短小了。我們要將它改為實現(xiàn)的是 StaticLinkList 方式的 destroy 函數(shù)。那么該如何操作呢?我們就需要在 StaticLinkList 類中加上它的析構(gòu)函數(shù)了,如下

~StaticLinkList()
{
    this->clear();
}

       我們再來斷點調(diào)試下,看看它調(diào)用的 destroy 函數(shù)究竟是哪個版本的實現(xiàn)。

典型問題分析(十五)

       我們看到這下調(diào)用的是 StaticLinkList 類方式的實現(xiàn)了。

       測試 6 :DTLib 庫是否有必要增加多維數(shù)組類呢?  多維數(shù)組的本質(zhì)其實就是數(shù)組的數(shù)組!

main.cpp 如下

#include 
#include "StaticLinkList.h"
#include "DynamicArray.h"

using namespace std;
using namespace DTLib;

int main()
{
    DynamicArray< DynamicArray > d;

    d.resize(3);

    for(int i=0; i

       我們來看看編譯運行結(jié)果

典型問題分析(十五)

       我們再將上面的第 16 行的 d[i].resize(3); 改為 d[i].resize(i + 1);

典型問題分析(十五)

       程序照常打印出了多維數(shù)組,因此我們的庫是沒必要進行多維數(shù)組類的開發(fā)的。因為多維數(shù)組的本質(zhì)就是數(shù)組的數(shù)組!通過今天的 bug 的調(diào)試,我們所寫的庫也是有一定的 bug 的,凡是軟件編寫的產(chǎn)品基本上都會出 bug,所以需要我們不停的迭代升級,去解決問題。


本文題目:典型問題分析(十五)-創(chuàng)新互聯(lián)
URL鏈接:http://weahome.cn/article/jpggg.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部