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

但我不调用复制构造函数!

4

3 回答 3

12

你永远不会调用复制构造函数。复制构造函数总是由编译器隐式调用。所以你需要学会识别可能被调用的情况。

当您将 const 引用附加到临时对象时

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

编译器有权执行临时对象的副本并需要一个可访问的副本构造函数(即使它实际上不会被调用)。这就是导致您的情况出现问题的原因。

换句话说,当您使某些类型不可复制时,您也放弃了将 const 引用附加到该类型的临时对象的可能性。

于 2009-12-19T11:54:15.793 回答
1

首先,从 SpecialFilter 中删除私有派生 - 没有必要,因为 Filter 已经不可复制。像这样的问题是为什么我认为像 boost::non_copyable 这样的解决方案是一个坏主意的原因——有更简单的方法可以说你不想要副本。

其次,尽管我不确定这是您的问题,但 C++ 表示,在几种情况下,编译器必须可以使用公共复制构造函数,即使编译器实际上并未使用它

于 2009-12-19T11:50:33.860 回答
0

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

于 2009-12-19T12:30:44.373 回答