Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!

like image 854
Karl von Moor Avatar asked Dec 19 '09 11:12

Karl von Moor


People also ask

Why is my copy constructor not being called?

The reason the copy constructor is not called is because the copy constructor itself is a function with one parameter. You didn't call such function,so it didn't execute.

Why there is no copy constructor in Java?

In Java it simply copies the reference. The object's state is not copied so implicitly calling the copy constructor makes no sense. And that's all there is to it really.

Is copy constructor is automatically created by compiler?

The compiler also creates a copy constructor if we don't write our own copy constructor. Unlike the default constructor, the body of the copy constructor created by the compiler is not empty, it copies all data members of the passed object to the object which is being created.

Does the compiler always provide a default copy constructor?

In C++, the compiler automatically generates the default constructor, copy constructor, copy-assignment operator, and destructor for a type if it does not declare its own. These functions are known as the special member functions, and they are what make simple user-defined types in C++ behave like structures do in C.


1 Answers

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.

like image 69
AnT Avatar answered Sep 29 '22 03:09

AnT