2016-07-31 28 views
0

爲什麼這段代碼是什麼導致刪除大小不匹配?

#include <functional> 
#include <iostream> 
#include <memory> 

struct Result { 
    string value; 
}; 

class BaseHandler { 
public: 
    BaseHandler() {} 
    void Handle() { std::cout << "Base Handler " << endl; } 

    ~BaseHandler() {} 
}; 

class Handler : public BaseHandler { 
public: 
    Handler(const Result& result) : result_(result) {} 
    void Handle() { std::cout << "Result: " << result_.value << endl; } 

    ~Handler() {} 

private: 
    Result result_; 
}; 

class Dispatcher { 
public: 
    void Dispatch() { 
    std::unique_ptr<BaseHandler> handler = create_handler_(); 
    handler->Handle(); 
    } 
    std::function<std::unique_ptr<BaseHandler>()> create_handler_; 
}; 

void SetHandler(Dispatcher* dispatcher, Result some_result) { 
    dispatcher->create_handler_ = 
     [some_result]() -> std::unique_ptr<BaseHandler> { 
    std::unique_ptr<BaseHandler> handler(new Handler(some_result)); 
    return handler; 
    }; 
} 

int main(int argc, char** argv) { 
    Result some_result; 
    some_result.value = "some_value"; 
    Dispatcher dispatcher; 
    SetHandler(&dispatcher, some_result); 

    dispatcher.Dispatch(); 
    return 0; 
} 

產生錯誤

F0731 11:28:05.092886 61642 debugallocation.cc:762] RAW: delete size mismatch: passed size 1 != true size 32 
    @   0x49f053 (anonymous namespace)::RawLogVA() 
    @   0x49ec05 base_raw_logging::RawLog() 
    @   0x56d51b tc_delete_sized 
    @   0x40e65b std::default_delete<>::operator()() 
    @   0x40e513 std::unique_ptr<>::~unique_ptr() 
    @   0x40da86 Dispatcher::Dispatch() 
    @   0x40d527 main 
    @  0x7f393a983ce8 __libc_start_main 
    @   0x40cef9 _start 
*** SIGABRT received by PID 61642 (TID 61642) from PID 61642; *** 
Aborted (core dumped) 
+1

你有沒有想過虛擬關鍵字的作用?現在是【找到一本好初學者書】的好時機(http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)並開始閱讀關於'虛擬「成員函數和遺產。 –

+0

不是downvoter,但我想我會讓你獨自一人。如果重複瑣事實際上是有用的可以爭論。也許你應該試試[tag:documentation]。 –

+0

@JoachimPileborg你注意到我們的貧民窟新貧民窟? –

回答

3

的問題是BaseHandler和處理程序沒有聲明虛析構函數。

如果Handle在BaseHandler中被標記爲虛擬並在Handler中重寫,那麼編譯器會產生一個關於析構函數未被聲明爲虛擬的錯誤。

下面的代碼按預期工作。

#include <functional> 
#include <iostream> 
#include <memory> 

struct Result { 
    string value; 
}; 

class BaseHandler { 
public: 
    BaseHandler() {} 
    virtual void Handle() { std::cout << "Base Handler " << endl; } 

    virtual ~BaseHandler() {} 
}; 

class Handler : public BaseHandler { 
public: 
    Handler(const Result& result) : result_(result) {} 
    void Handle() override { std::cout << "Result: " << result_.value << endl; } 

    virtual ~Handler() {} 

private: 
    Result result_; 
}; 

class Dispatcher { 
public: 
    void Dispatch() { 
    std::unique_ptr<BaseHandler> handler = create_handler_(); 
    handler->Handle(); 
    } 
    std::function<std::unique_ptr<BaseHandler>()> create_handler_; 
}; 

void SetHandler(Dispatcher* dispatcher, Result some_result) { 
    dispatcher->create_handler_ = 
     [some_result]() -> std::unique_ptr<BaseHandler> { 
    std::unique_ptr<BaseHandler> handler(new Handler(some_result)); 
    return handler; 
    }; 
} 

int main(int argc, char** argv) { 
    Result some_result; 
    some_result.value = "some_value"; 
    Dispatcher dispatcher; 
    SetHandler(&dispatcher, some_result); 

    dispatcher.Dispatch(); 
    return 0; 
}