2013-03-07 83 views
2
struct Abstract{ 
    virtual void methodA() = 0; 
}; 

struct Test : public Abstract{ 
    virtual void methodA(){ 
     printf("Test message"); 
    } 
}; 

class Foo{ 
    Abstract* abs; //I made it this way so that an instance of Foo 
        //can easily switch between any class that implements 
        //Abstract 
public: 
    virtual ~Foo(){ 
     delete abs; //free abs 
    } 

    void setAbs(Abstract* a){ 
     abs = a; //is there any other way to do this? 
    } 

    void changeAbs()//method to switch abs 

    void show(){ 
     abs->methodA(); 
    } 
}; 

int main(){ 
    Test *test = new Test(); 
// Test test; //local instantiation will throw a segmentation fault 
       //because abs is freed in the desctructor of Foo 
    Foo foo; 
    foo.setAbs(test); 
    foo.show(); 

// delete test; //using a pointer is fine unless freed 
    return 0; 
} 

我的擔憂是:指針和抽象類

  1. 如果我免費ABS在析構函數和用戶忘記釋放他的目標實現摘要,或者如果用戶做這種方式setAbs(new Test()),會有泄漏。

  2. 如果我釋放在析構函數ABS它會拋出一個分段錯誤,如果用戶實例本地測試或他用一個指針,並刪除它最終自己。

  3. Abstract abs也是不允許的,因爲它是一個抽象類

我想改變setAbs(),以這樣的:

void setAbs(Abstract* a){ 
    abs = new Abstract(*a); //but copying like a normal class doesn't work on abstract classes 
} 

我的問題是,是否有任何其他方式實現setAbs(),以便它將傳遞參數的副本?

如果沒有其他辦法,我只是讓freeing成爲用戶的工作。

+0

呃,'std :: shared_ptr'? – 2013-03-07 04:09:54

+0

請注意,'Abstract'沒有虛擬析構函數,所以'delete abs'會產生未定義的行爲。 – 2013-03-07 14:20:15

回答

4

這裏的根本問題是,你沒有清楚說明誰擁有這個內存。

如果你的類擁有它,那麼在你的析構函數中釋放是安全的。那麼,不是你寫的方式,而是理論上的。請閱讀The Rule of Three

如果您的課程確實是而不是擁有指針,那麼請不要取消分配它。這不是你的解除分配,所以使用它,不要再做了。

處理內存的安全方法是通過隱式地強制執行一項關於誰對什麼負責的合同。如果用戶繼續前進,並且delete是您的指針,那麼告訴他們停止;這不是他們的業務。您可以使用std::unique_ptr指針和get()函數執行相同的操作。班級不會阻止你,它怎麼可能?它不關心你是否射擊自己的腳。 RTFM。

說到std::unique_ptr ...爲什麼不使用它(或std::shared_ptr如果合適)?這是一個解決的問題,不需要在這裏提出自己的解決方案。