2013-03-28 67 views
2

我使用Qt在C++和行爲枚舉正在與一個枚舉掙扎。考慮像下面這樣的情況:C++ - 在成員對象

克隆GitHub上:https://github.com/jif/enum

// memberclass.h ======================================================= 
#ifndef MEMBERCLASS_H 
#define MEMBERCLASS_H 

#include <QObject> 

class MemberClass : public QObject 
{ 
    Q_OBJECT 
public: 
    enum ErrorType { 
     NoError, 
     IsError 
    }; 
    explicit MemberClass(QObject *parent = 0); 
    void setError(ErrorType errorType); 
    MemberClass::ErrorType error() const; 
    void otherMethod(); 
private: 
    MemberClass::ErrorType mError; 
}; 

#endif // MEMBERCLASS_H 

// memberclass.cpp ======================================================= 
#include "memberclass.h" 
#include <QDebug> 

MemberClass::MemberClass(QObject *parent) : 
    QObject(parent) 
{ 
    mError = NoError; 
    qDebug() << "mError initialized."; 
} 
MemberClass::ErrorType MemberClass::error() const { 
    return mError; 
} 
void MemberClass::setError(ErrorType errorType) { 
    mError = errorType; 
} 
void MemberClass::otherMethod() { 
    qDebug() << " In otherMethod()..."; 
    qDebug() << "  mError = " << mError; 
    qDebug() << "  NoError = " << NoError; 
    qDebug() << "  IsError = " << IsError; 
    qDebug() << " End otherMethod()"; 
} 

// parentclass.h ======================================================= 
#ifndef PARENTCLASS_H 
#define PARENTCLASS_H 

#include <QObject> 
#include "memberclass.h" 

class ParentClass : public QObject 
{ 
    Q_OBJECT 
public: 
    explicit ParentClass(QObject *parent = 0); 
    void testEnumStuff(); 
private: 
    MemberClass objectMember; 
    MemberClass *pointerMember; 
}; 

#endif // PARENTCLASS_H 

// parentclass.cpp ======================================================= 
#include "parentclass.h" 
#include <QDebug> 

ParentClass::ParentClass(QObject *parent) : 
    QObject(parent) 
{ 
    pointerMember = new MemberClass(this); 
} 
void ParentClass::testEnumStuff() { 
    qDebug() << "Just initialized..."; 
    qDebug() << " pointerMember::mError = " << pointerMember->error(); 
    qDebug() << " objectMember::mError = " << objectMember.error(); 
    qDebug() << "Calling otherMethod() on each member..."; 
    qDebug() << " In pointerMember..."; 
    pointerMember->otherMethod(); 
    qDebug() << " In objectMember..."; 
    objectMember.otherMethod(); 
    qDebug() << " pointerMember::mError = " << pointerMember->error(); 
    qDebug() << " objectMember::mError = " << objectMember.error(); 
    qDebug() << "Done."; 
} 

// main.cpp ======================================================= 
#include <QCoreApplication> 
#include "parentclass.h" 

int main(int argc, char *argv[]) 
{ 
    QCoreApplication a(argc, argv); 
    ParentClass parent; 
    parent.testEnumStuff(); 
    return a.exec(); 
} 


// enum.pro ======================================================= 
QT  += core 

QT  -= gui 

TARGET = enum 
CONFIG += console 
CONFIG -= app_bundle 

TEMPLATE = app 


SOURCES += main.cpp \ 
    parentclass.cpp \ 
    memberclass.cpp 

HEADERS += \ 
    parentclass.h \ 
    memberclass.h 

ErrorType類型的變量mError工作不能按預期工作(它在執行過程中呈現奇怪的和不一致的值)。

我得到的輸出是這樣的:

mError initialized. 
mError initialized.  
Just initialized... 
    pointerMember::mError = 0 
    objectMember::mError = 0 
Calling otherMethod() on each member... 
    In pointerMember... 
    In otherMethod()... 
     mError = 0 
     NoError = 0 
     IsError = 1 
    End otherMethod() 
    In objectMember... 
    In otherMethod()... 
     mError = 13498688 
     NoError = 0 
     IsError = 1 
    End otherMethod() 
    pointerMember::mError = 0 
    objectMember::mError = 13498688 
Done. 
+0

後凡'mError'初始化一個完整的例子 – 2013-03-28 05:24:10

+0

? – user93353 2013-03-28 05:31:11

+0

它確實看起來像初始化錯誤。你應該這樣寫:'mError = NoError;'在你的MemberOfMyClass構造函數中。 – Amartel 2013-03-28 06:48:22

回答

0

如果堆棧像定義對象:

MemberOfMyClass member; 

,當你走出去的範圍,你的對象信息丟失

9

您沒有爲MemberClass定義默認構造函數,並且提供了一個隱式的編譯器來初始化ParentClass中的objectMember。隱含的構造函數不會爲你初始化mError,因此你得到的是隨機值。

要麼添加一個明確的默認構造函數來MemberClass

MemberClass::MemberClass() : 
    QObject(NULL), mError(NoError) 
{ 
} 

或成員初始化ParentClass

ParentClass::ParentClass(QObject *parent) : 
    QObject(parent), objectMember(NULL) 
{ 
    pointerMember = new MemberClass(this); 
} 
+0

我在MemberClass('qDebug()<<「mError initialized。」;'')的構造函數中添加了一個調試打印,它打印出'objectMember'和'pointerMember'兩個對象,告訴我在這兩種情況下都使用了我的顯式構造函數, 'mError'已正確初始化... – Jay 2013-04-02 15:15:41

+0

這不與可用的可能性相關聯。我想說問題的一部分還在於你使用了顯式默認參數,這對我來說毫無意義。除此之外,您編寫代碼的方式可以解釋對我的調用,因爲您沒有編寫默認或複製構造函數,而是提供了自己的獨立構造函數。嘗試初始化pointerMember(新MemberClass(this)),而不是在正文中,如果您的inits數停止打印兩次,我不會感到驚訝。並在你的調試中打印出'父'的地址。 另外你的代碼有明顯的內存泄漏。 – UpAndAdam 2013-04-08 17:02:09

1

在你這裏的會員

private: 
    MemberClass objectMember; 

你」的聲明不要爲構造函數提供參數。 它調用QObject的默認構造函數(它不在你的代碼中)並且不初始化枚舉。

0

的成員類單參數構造具有線< < 「mError初始化。」;這在輸出中不存在。編譯器生成的默認構造函數是無能的成員變量的期望值的,因此,如果分配給這些內存有垃圾,這些垃圾被泄露..

+0

pointerMember = new MemberClass(this);在構造函數執行完成之前傳遞它。類型轉換是否仍然成功? – 2013-04-02 19:16:03

+0

對不起,我更新了帖子中的代碼,但沒有輸出:(行輸出中出現 – Jay 2013-04-03 20:49:40

0

我只是複製並粘貼代碼到一個乾淨的項目。當使用MSVC2010編譯Qt 4.8.0時,一切看起來都正常。你是否重建過你的項目並重新運行qmake?

0

我克隆你的代碼運行它,也沒有問題。
我建議你清理你的項目並重新構建它。 代碼看起來也很好。我認爲編譯器緩存在代碼修改期間被損壞(有時會發生)並且生成了錯誤的代碼,乾淨的項目應該修復它。

0

你永遠不會初始化在父類的構造函數的「objectMember」值,但是你做初始化‘pointerMember’。我敢打賭,「objectMember」也是在測試中給你提供問題的價值。我沒有QT,但如果您在初始化pointerMember後向該構造函數添加了

objectmember = *pointerMember; 

?從我玩過C++開始就有點過了,所以我可能會漏掉一些明顯的東西,但我敢打賭這是你的問題。

另請注意,上次我玩它時,Visual Studio的調試器傾向於將所有未初始化的值設置爲0,以供程序員使用。這種情況一旦代碼實際上已經被編譯就不會發生(儘管我相信有些編譯器可以這樣做,比如GCC),所以這可能就是爲什麼你看到這個錯誤,而其他的則不然。正因爲如此,這可能有助於將您要查找的值設置爲「IsError」 - 這樣,您要查找的值將爲1,而不是默認的未初始化值。

1

你事實上並沒有得到一個自動生成的構造函數。這樣做的原因是你只會在一個沒有定義構造函數的類中被賦予這樣的構造函數。你爲MemberClass(QObject * parent = 0)定義了一個構造函數,但是因爲它存在,所以你沒有分配一個自動生成的noargs構造函數。

類似但相關的例子可以說明類的問題:

class Base 
{ 
    /*Has a constructor therefore does not get a free 
    noargs constructor*/ 
    Base(int i) {}; 
}; 

class Derived : public Base 
{ 
}; 

int main() 
{ 
    /*Not actually possible because Derived will get a free noargs constructor 
     which will attempt to invoke the non existant no args constructor of Base. 
    */ 
    Derived d; 

    return 0; 
} 

你可以看到結果here

+0

'MemberClass'的構造函數初始化'mError'。請參閱原始文章 – Jay 2013-04-11 03:47:33

+0

除了無參數構造函數(你沒有)將被調用,例如MemberClass objectMember; //你需要一個沒有參數的構造函數 – DuncanACoulter 2013-04-11 13:05:30