Конструктор копирования не вызывается, но компилятор жалуется, что нет
учитывая следующий код:
#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));]
но я не вызываю конструктор копирования!
3 ответов
вы никогда не вызов конструктора копирования. Конструктор копирования всегда вызывается компилятором неявно. Поэтому вам нужно научиться распознавать ситуации, когда это может быть вызвано.
при присоединении ссылки const к временному объекту
...
return filter(channel, SpecialFilter(123, 321));
...
компилятор имеет право выполнить копию временного объекта и потребовать доступного конструктора копирования (даже если он фактически не будет вызван). Это то, что вызывает проблемы в вашем случай.
другими словами, когда вы делаете какой-либо тип не копируемым, вы также отказываетесь от возможности прикреплять ссылки const к временным объектам этого типа.
во-первых, удалите частный вывод из SpecialFilter-это не обязательно, так как фильтр уже не копируется. Такие проблемы, как это, почему я думаю, что такие решения, как boost::non_copyable - плохая идея-есть более простые способы сказать, что вы не хотите копий.
во-вторых, хотя я не уверен, что это ваша проблема, C++ говорит, что открытый конструктор копирования должен быть доступен компилятору в нескольких circimstances,даже если компилятор не использует это.
помните, когда вы передаете объект и возвращаете объект по значению -- > вызывается конструктор копирования.