2013-08-12 63 views
0

我很困惑在構造函數(如下圖所示)或方法本身中動態分配(QFile *和QTextStream *)的位置,如果方法GetCurrentStream()應該改變價值流。qt中的動態成員分配

頭文件

class QLogger { 
public: 
    explicit QLogger(); 
    ~QLogger(); 
    QTextStream& GetCurrenStream(); 
private: 
    QFile *file; 
    QTextStream *stream; 
}; 

,並在相關的.cpp

QLogger::QLogger() { 
    file = new QFile; 
    stream = new QTextStream; 
} 

~QLogger() { 
    delete file; 
    delete stream; 
} 

QTextStream& GetCurrenStream() { 
    ... 
    return *stream; 
} 

何地釋放在析構函數存儲?

+1

我寧願構造函數初始化列表。我還會提供或防止複製構建和分配,因爲它現在可能會有未來的不好的意外。這是常見的錯誤模式。 – user2672165

+1

我不是100%確定的,如果打電話給你的班級,QLogger是個好主意。 Q *是Qt類。技術上沒問題。但是也許Digia在他們的下一個版本中引入了一個QLogger類。這可能會變得有點混亂。 – Greenflow

+1

另外我不會將我的類命名爲Q,因爲它可以將它與Qt自己的類區分開來。 – user2672165

回答

1

你所做的似乎是正確的。您在構造函數中分配對象,並在析構函數中刪除它們。

但是,它不應該按原樣構建,因爲GetCurrentStream()應該返回對流對象的引用,並且您當前正在返回一個指針。

類似下面的代碼示例可能是缺少的東西。

QTextStream& GetCurrenStream() { 
    ... 
    return *stream; 
} 
2

如果你能夠提供你的對象,具有所有必要的數據將被建造的那一刻,你應該把所有的初始化在構造函數中,爲它創建實際的對象。這樣,你可以確保,當你使用它的時候你的對象就會準備好。
如果你沒有使用任何特殊模式,你的獲得者不應該創建他們返回的對象,而應該創建一個引用,就像你在GetCurrentStream()中做的那樣。其次,使用析構函數,這是從分配的對象中釋放內存的實際位置。如果你有解除分配過程可能是危險的,你應該爲此提供一個額外的方法,因爲如果析構函數失敗了,你會遇到內存泄漏。另外,絕對不要在析構函數中拋出異常!

如果你需要改變一個指向對象的指針(如GetCurrentStream(),你應該提供一個不同的方法來改變流,並在這個方法中處理必要的重新分配)。
還記得參考返回一個指針像

return *stream; //return reference to actual object, not the pointer! 

總而言之,這看起來不錯,你做了那裏。

1

考慮使用智能指針來管理動態分配的對象。

在Qt中你可以使用QScopedPointer(在C++ 11中也有std::unique_ptr)。

(同樣如在上述評論提到:Q *名稱由Qt的東西基本上保留)

class Logger { 
public: 
    Logger(); 
    QTextStream& getCurrenStream(); 
private: 
    QScopedPointer<QFile> file; 
    QScopedPointer<QTextStream> stream; 
}; 

Logger::Logger() 
    : file(new QFile) 
    , stream(new QTextStream) 
{ 
} 

QTextStream& getCurrenStream() { 
    // ... 
    return stream.data(); // stream.get() with std::unique_ptr 
} 

存儲器將自動智能指針(解除分配與QSharedPointerstd::shared_ptr還另外引用計數,從而存儲器是在存在共享指針的副本時未釋放)。

+0

使用智能指針是否安全? – elgolondrino

+0

在這種情況下是安全的。但是不要使用智能指針併爲其他QObject指定QObject父項(您將得到雙重釋放)。 – hluk

+0

如果在初始化列表中初始化文件和流,則可能還會考慮聲明'QFile * const file'和'QTextStream * const stream'。如果使用QScopedPointer,當然不會。 :-) – Greenflow