2009-12-19 11 views
6

Dato il seguente codice:Copia costruttore non chiama, ma il compilatore si lamenta che non c'è

#include <boost/noncopyable.hpp> 

enum Error { ERR_OK=0 }; 

struct Filter : private boost::noncopyable 
{ 
    Filter() {} 
    virtual ~Filter() {} 

    virtual int filter(int* data) const = 0; 

}; 

struct SpecialFilter : public Filter, private boost::noncopyable 
{ 
    inline SpecialFilter(unsigned int min, unsigned int max) : min(min), max(max) {} 
    virtual ~SpecialFilter() {} 

    virtual int filter(int* data) const 
    { 
    // ... 
    return ERR_OK; 
    } 

    unsigned int min; 
    unsigned int max; 
}; 

struct AClass 
{ 
    AClass() {} 
    AClass(const AClass& other) {} 
    ~AClass() {} 

    int specialFilter(int channel, int minThreshold, int maxThreshold) 
    { 
    // ... 
    return filter(channel, SpecialFilter(123, 321)); 
    } 

    int filter(int channel, const Filter& filter) 
    { 
    // ... 
    return ERR_OK; 
    } 

}; 

mio compilatore (GCC 4.2) si lamenta:

- warning: direct base ‘boost::noncopyable_::noncopyable’ inaccessible in ‘SpecialFilter’ due to ambiguity 
- noncopyable.hpp: In copy constructor ‘Filter::Filter(const Filter&)’: 
- noncopyable.hpp:27: error: ‘boost::noncopyable_::noncopyable::noncopyable(const boost::noncopyable_::noncopyable&)’ is private 
- synthezised method first required here: [return filter(channel, SpecialFilter(123, 321));] 

Ma io non chiamare il costruttore di copia !

risposta

11

Non si chiama mai il costruttore di copie. Il costruttore di copie viene sempre chiamato implicitamente dal compilatore. Quindi devi imparare a riconoscere le situazioni in cui potrebbe essere chiamato.

Quando si collega un riferimento const a un oggetto temporaneo

... 
return filter(channel, SpecialFilter(123, 321)); 
... 

il compilatore ha il diritto di eseguire una copia dell'oggetto temporaneo e richiedono un costruttore di copia accessibile (anche se non sarà in realtà chiamato). Questo è ciò che sta causando il problema nel tuo caso.

In altre parole, quando si rende un tipo non copiabile, si rinuncia anche alla possibilità di allegare riferimenti const a oggetti temporanei di quel tipo.

+0

Grazie. Ho imparato qualcosa di nuovo ... –

1

In primo luogo, rimuovere la derivazione privata da SpecialFilter - non è necessario, poiché Filtro non è già copiato. Problemi come questo sono il motivo per cui penso che soluzioni come boost :: non_copyable siano una cattiva idea - ci sono modi più semplici per dire che non vuoi copie.

In secondo luogo, anche se non sono sicuro che questo sia il tuo problema, C++ dice che un costruttore di copie pubbliche deve essere disponibile per il compilatore in varie circostanze, anche se il compilatore non lo usa effettivamente.

0

Ricordare quando si passa oggetto e restituire oggetto in base al valore -> viene richiamato il costruttore della copia.

Problemi correlati