2009-12-19 4 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를 참조를 연결하면

컴파일러는 임시 객체의 복사본을 수행하고 그것을 실제로 호출되지 않습니다 경우에도 (접근 복사 생성자를 요구할 권리가있다). 이것은 귀하의 경우에 문제를 일으키는 원인입니다.

즉, 일부 유형을 복사 할 수 없게 만들 때 해당 유형의 임시 객체에 const 참조를 첨부 할 수있는 가능성도 포기합니다.

+0

감사합니다. 나는 새로운 것을 배웠다 ... –

1

먼저 SpecialFilter에서 비공개 파생물을 제거하십시오. Filter는 이미 복사 할 수 없기 때문에 필요하지 않습니다. 이와 같은 문제가 boost :: non_copyable과 같은 솔루션이 나쁜 아이디어라고 생각하는 이유입니다. 사본을 원하지 않는다는 단순한 방법이 있습니다.

둘째, 이것이 문제가 아니라고 확신하지만 컴파일러에서 실제로 사용하지 않더라도 공용 복사본 생성자를 컴파일러에서 사용할 수 있어야한다고합니다..

0

개체를 전달하고 값으로 개체를 반환 할 때 -> 복사 생성자가 호출된다는 것을 기억하십시오.