2011-08-03 20 views
0

我有一個非常奇怪的問題,我希望有人遇到過。在析構函數中調用成員變量的虛函數會導致seg錯誤

class Letter 
{ 
public: 
    Letter() 
    virtual ~Letter() 
    virtual std::string get() const = 0; 
}; 

class A : public Letter 
{ 
public: 
    A() 
    ~A() 
    virtual std::string get() const { return "A"; } 
}; 

class Board 
{ 
public: 
    Board(){} 
    ~Board() 
    { 
     std::cout << "Removing: " << letter->get() << std::endl; 
     delete letter; 
    } 
    void setLetter(Letter * l) { letter = l } 
private: 
    Letter * letter; 
} 

int main() 
{ 
    Board b; 
    b.setLetter(new A()); 
} 

該程序使得賽格故障時局超出範圍在哪裏)的虛擬功能信紙>得到(被稱爲在析構函數的行。我正在使用gcc 4.1.2。有任何想法嗎?

UPDATE

好,似乎所發生的情況在實際的代碼是這樣的等價的:

class Board 
{ 
public: 
    Board(){} 
    ~Board() 
    { 
     std::cout << "Removing: " << letter->get() << std::endl; 
    } 
    void setLetter(Letter * l) { letter = l; } 
private: 
    Letter* letter; 
}; 

int main() 
{ 
    Board b; 
    A a; 
    b.setLetter(&a); 

    return 0; 
} 

在這種情況下,已經超出了範圍,當虛函數被調用。

+1

是不是〜Letter()或〜A()做了什麼? –

+1

你能提供一個重現錯誤並實際編譯的最小例子嗎?我修正了你的代碼片段中的錯誤,並且運行正常。 –

+0

嘗試在聲明後加上一些分號......可能會這樣做。 –

回答

0

我不知道一個對象被傳遞到從棧setLetter(),所以A要出去的範圍B之前。

Board b; 
A a; 
b.setLetter(&a); 
-1

有些編譯器不允許Plain C/C++構造函數或析構函數調用虛方法,它們都不像(ANSI)C++規範。並不建議。

有時候這個要求很有用。像Object Pascal顯式的一些語言允許在構造函數和析構函數中調用虛擬方法。

有一兩件事你可以做它使用「假虛構造模式」:

class MyClass 
{ 
    public: 
    // constructor 
    MyClass 
    { 
     // anything but virtual methods 
    } 

    // destructor 
    ~MyClass 
    { 
     // anything but virtual methods 
    } 

    virtual void MyFakeConstructor() 
    { 
     MyVirtualMethod(); 
    } 

    virtual void MyFakeDestructor() 
    { 
     MyVirtualMethod(); 
    } 

    virtual void MyVirtualMethod() 
    { 
     // more stuff 
    } 

    // more members 
} 

int main(char[][] Args) 
{ 
    MyClass MyObject = new MyClass(); 
    MyObject->MyFakeConstructor(); // <-- calls "MyVirtualMethod()" 

    MyObject->DoSomething1(); 
    MyObject->DoSomething2(); 
    MyObject->DoSomething3(); 

    MyObject->MyFakeDestructor(); // <-- calls "MyVirtualMethod()" 
    delete MyObject; 

    return 0; 
} // int main() 

另一種解決方案是其你安排你的代碼,以便您明確調用析構函數之外的虛方法。

乾杯。

+1

這是指調用同一類的虛擬方法。 –

1

我只能猜測你試圖將從get()返回的std :: string轉換爲char *。否則,我看不到墜機的原因。

0
#include <iostream> 
#include <string> 
using namespace std; 

class Letter 
{ 
public: 
    Letter() {} 
    virtual ~Letter() {} 
    virtual std::string get() const = 0; 
}; 

class A : public Letter 
{ 
public: 
    A() {} 
    ~A() {} 
    virtual std::string get() const { return "A"; } 
}; 

class Board 
{ 
public: 
    Board(){} 
    ~Board() 
    { 
     std::cout << "Removing: " << letter->get() << std::endl; 
     delete letter; 
    } 
    void setLetter(Letter * l) { letter = l; } 
private: 
    Letter * letter; 
}; 

int main() 
{ 
    Board b; 
    b.setLetter(new A()); 
    return 0; 
} 

在gcc中沒有問題4.5.2

相關問題