2012-02-29 3 views
5

Questo sembra davvero un bug in Qt. Qualcuno ha una soluzione o dovrei archiviarla come un bug?Impossibile accedere ad un membro privato dichiarato nella classe 'QReadWriteLock'Error errore C2248:' QReadWriteLock :: QReadWriteLock '

#include <QReadWriteLock> 

class FileInfoWrapper { 

public: 
    explicit FileInfoWrapper(const QFileInfo& _fileInfo); 
    ~FileInfoWrapper(); 

private: // also tried public 
    mutable QReadWriteLock lock_; 

Prima ancora di usarlo, ottengo l'errore:

Error 1 error C2248: 'QReadWriteLock::QReadWriteLock' : cannot access private member declared in class 'QReadWriteLock'

Non importa se si tratta di privati ​​/ pubblici o quali classi che includono. Non mi sembra di essere in grado di crearlo in pila. Invece ho creato uno sul mucchio usando 'nuovo', ma quando provo ad eliminarlo nel costruttore miei crash dell'applicazione con:

Unhandled exception at 0x5090f39a (QtCored4.dll) in MyApp.exe: 0xC0000005: Access violation reading location 0xfeeeff0e.

stack di chiamate:

QtCored4.dll!QHash::~QHash() Line 283 + 0xa bytes C++ QtCored4.dll!QReadWriteLockPrivate::~QReadWriteLockPrivate() + 0x38 bytes C++ QtCored4.dll!QReadWriteLockPrivate::`scalar deleting destructor'() + 0xf bytes C++ QtCored4.dll!QReadWriteLock::~QReadWriteLock() Line 137 + 0x1e bytes C++ CloudSync.exe!FileInfoWrapper::~FileInfoWrapper() Line 76 + 0x15 bytes C++

La variabile 'd' QReadWriteLockPrivate sembra essere cancellato due volte. Tuttavia, questo funziona in un'altra classe in cui dovevo anche creare il blocco sull'heap e quindi cancellarlo nel costruttore.

Esecuzione di Qt 4.8.0 in Visual Studio. Ho avuto lo stesso problema in Qt creatore 4.7.4.

+0

Impossibile riprodurre con Qt 4.7.4, MinGW, Windows 7 x64. –

risposta

6

Devi usare un puntatore perché QReadWriteLock non è copiabile (usa Q_DISABLE_COPY) e si sono in qualche modo la copia dei FileInfoWrapper oggetti (memorizzandoli in un contenitore per esempio).
Quindi l'indirizzo del puntatore è condiviso tra quelle copie e cancellato una volta per ogni copia.

È possibile avvolgere il puntatore all'interno di un puntatore intelligente, in modo che la cancellazione si verifichi solo quando viene cancellata l'ultima copia dell'oggetto.

QSharedPointer<QReadWriteLock> lock_; 
+0

Quindi non c'è bisogno di cancellarlo nel costruttore di fileWrappers? E sì, ho una lista di questi file, ma non mi riposo ancora. In teoria, avrò solo un blocco che condividono tutti gli oggetti? E se ho una classe che ne avrò solo uno e voglio dichiararlo nello stack, posso usare la macro Q_DISABLE_COPY nella mia classe allora? – chikuba

+0

** 1. ** Sì, non sarà più necessario eliminarlo esplicitamente nel distruttore. ** 2. ** I blocchi saranno condivisi tra le copie degli stessi oggetti 'FileInfoWrapper', se si creano da zero 2 oggetti' FileInfoWrapper' (sebbene il costruttore prenda un QFileInfo'), ci saranno 2 blocchi indipendenti. ** 3. ** Se si intende consentire solo un'istanza di una classe per l'intera applicazione, si dovrebbe provare invece un "modello singleton". – alexisdm

+0

Non copio mai FileInfoWrapper, ho solo un sacco di istanze dell'oggetto. Ma intendi se ho uno degli oggetti fuori dalla lista? Non ha senso – chikuba