簡體   English   中英

為什么通過純虛基 class 調用方法導致 Seg Fault

[英]Why Calling method through pure-virtual base class causing Seg Fault

我有一個由四個抽象基 class 定義定義的接口。在我現在擁有的實現中,我在通過抽象 class 指針調用具體的 class 方法時遇到分段錯誤。

直接調用具體的 class 方法可以正常工作。

    #include <iostream> 
    
    enum Result_t 
    { 
        SUCCESS            
    };
    
    class DataCallback {
        public:
        virtual Result_t Callback(int32_t data) = 0;
        virtual ~DataCallback(){}
    };
    
    class DataCallback_Actual {
        public:
            Result_t Callback(int32_t data)
            {
                std::cout << m_name << ": int data update: " << data << std::endl;
                return SUCCESS;
            }
    
            DataCallback_Actual(const std::string & name):
            m_name(name) 
            {
                std::cout << "constructor DataCallback_Actual::DataCallback_Actual(" << m_name << ") @ 0x" << std::hex << this << std::endl;
            }
    
        private:
            std::string m_name;
    };
    
    int main(int argv, char **argc)
    {
        // Create a pointer to the concrete class
        DataCallback_Actual * pDataCallbackTwo_A = new DataCallback_Actual(std::string("Object-Two-Int"));
DataCallback_Actual(std::string("Object-Two-Int")));
    
        DataCallback * pDataCallbackTwo = (DataCallback *) pDataCallbackTwo_A;
    
        //
        // TODO: Why does the first call work but I get a segfault 
        //       when calling through the abstract pointer...
        //
        pDataCallbackTwo_A->Callback(10);
        pDataCallbackTwo->Callback(12);
    }

當我執行示例程序時,Callback() 方法在使用 _A 指針時工作正常,但在通過基本 class 指針調用時出現分段錯誤......指針的值相同。

gdb 序列看起來像..

Breakpoint 1, main (argv=21845, argc=0x7fffffffe1c0) at abstractFail.cpp:34
34  {
(gdb) n
36      DataCallback_Actual * pDataCallbackTwo_A = new DataCallback_Actual(std::string("Object-Two-Int"));
(gdb) n
constructor DataCallback_Actual::DataCallback_Actual(Object-Two-Int) @ 0x0x55555556aeb0
40      DataCallback * pDataCallbackTwo = (DataCallback *) pDataCallbackTwo_A;
(gdb) n
47      pDataCallbackTwo_A->Callback(10);
(gdb) p pDataCallbackTwo_A
$1 = (DataCallback_Actual *) 0x55555556aeb0
(gdb) p pDataCallbackTwo
$2 = (DataCallback *) 0x55555556aeb0
(gdb) n
Object-Two-Int: int data update: a
48      pDataCallbackTwo->Callback(12);
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
0x00005555555553f8 in main (argv=1, argc=0x7fffffffe308) at abstractFail.cpp:48
48      pDataCallbackTwo->Callback(12);
(gdb) 

我對另一個抽象/具體的 class 對使用相同的模式,它工作正常。 我不喜歡這兩種模式是相同的,但一種是段錯誤,一種不是。

這是罪魁禍首:

DataCallback *pDataCallbackTwo = (DataCallback *)pDataCallbackTwo_A

您將pDataCallbackTwo_A reinterpret_cast為它不是的東西並像訪問它一樣訪問它,這會導致未定義的行為。

通過繼承DataCallback使DataCallback_Actual成為DataCallback的一種:

class DataCallback_Actual : public DataCallback { 

然后你甚至不需要演員表:

DataCallback *pDataCallbackTwo = pDataCallbackTwo_A;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM