Pergunta

Dado o seguinte código:

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

};

Meu compilador (GCC 4.2) reclama:

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

Mas eu não chamo o construtor de cópias!

Foi útil?

Solução

Você nunca liga para o construtor de cópias. O construtor de cópias é sempre chamado para você implicitamente pelo compilador. Portanto, você precisa aprender a reconhecer situações em que isso pode ser chamado.

Quando você anexa uma referência constante a um objeto temporário

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

O compilador tem o direito de executar uma cópia do objeto temporário e requer um construtor de cópia acessível (mesmo que não seja realmente chamado). É isso que está causando o problema no seu caso.

Em outras palavras, quando você torna algum tipo não copie, você também desiste da possibilidade de anexar referências constantes a objetos temporários desse tipo.

Outras dicas

Em primeiro lugar, remova a derivação privada do SpecialFilter - não é necessário, pois o filtro já não é copável. Problemas como isso são por isso que acho que soluções como Boost :: não_copyable são uma má idéia - existem maneiras mais simples de dizer que você não quer cópias.

Em segundo lugar, embora eu não tenha certeza se esse é o seu problema, C ++ diz que um construtor de cópia pública deve estar disponível para o compilador sob várias circimstâncias, Mesmo que o compilador não use realmente.

Lembre -se de quando você passa o objeto e retorna objeto por valor -> Copiar construtor é invocado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top