2009-12-19 63 views
6

考慮下面的代碼:拷貝構造函數不叫,但編譯器抱怨,有沒有

#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; 
    } 

}; 

我的編譯器(GCC 4.2)抱怨:

- 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));] 

但我不調用拷貝構造函數!

回答

11

你永遠不會調用複製構造函數。複製構造函數總是由編譯器隱式調用。所以你需要學習識別可能被調用的情況。

當您將一個常量引用臨時對象

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

編譯器必須執行臨時對象的副本,需要訪問的拷貝構造函數(即使它不會被真正稱爲右)。這是你的情況導致問題的原因。

換句話說,當你讓某些類型不可複製時,你也放棄了將const引用附加到該類型的臨時對象的可能性。

+0

謝謝。我學到了一些新東西...... – 2009-12-19 12:02:39

1

首先,從SpecialFilter中刪除私有派生 - 這不是必需的,因爲Filter已經不可複製。像這樣的問題是爲什麼我認爲像boost :: non_copyable這樣的解決方案是一個糟糕的主意 - 有更簡單的方式說你不想拷貝。其次,雖然我不確定這是你的問題,但C++認爲即使編譯器實際上沒有使用,公共拷貝構造函數也必須可用於編譯器幾種情況下,即

0

記住當你傳遞對象並通過值返回對象 - >複製構造函數被調用。

相關問題