简体   繁体   中英

Copy constructor not called, but compiler complains that there's no

Given the following code:

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

};

My compiler (GCC 4.2) complains:

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

But I don't call the copy constructor!

You never call copy constructor. The copy constructor is always called for you implicitly by the compiler. So you need to learn to recognize situations when it might be called.

When you attach a const reference to a temporary object

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

the compiler has the right to perform a copy of the temporary object and require an accessible copy constructor (even if it won't be actually called). This is what is causing the problem in your case.

In other words, when you make some type non-copyable, you also give up the possibility to attach const references to temporary objects of that type.

Firstly, remove the private derivation from SpecialFilter - it is not necessary, as Filter is already not copyable. Problems like this are why I think solutions like boost::non_copyable are a bad idea - there are simpler ways of saying you don't want copies.

Secondly, though I'm not sure this is your problem, C++ says that a public copy constructor must be available to the compiler under several circimstances, even if the compiler does not actually use it .

请记住,当您传递对象并按值返回对象时 - >调用复制构造函数。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM