1

我有几个我不想被复制的类,其中一些类有指针数据成员。为了使这些类不可复制,我私下继承了以下类模板:

template <class T>
class Uncopyable
{
  protected:
    Uncopyable() {}
    virtual ~Uncopyable() {}
  private:
    Uncopyable(const Uncopyable &);
    T & operator=(const T&);
};

我这样使用:

class Entity : private Uncopyable<Entity> { }

这很好用,但是当我使用 -Weffc++ 编译时,我仍然收到以下警告:

class Entity has pointer data members
but does not override Entity(const Entity&)
or operator=(const Entity&)

为什么它仍然给我这个警告?

4

1 回答 1

8

C++ 说

因为如果用户未声明复制赋值运算符,则会为类隐式声明,因此基类复制赋值运算符始终被派生类的复制赋值运算符隐藏(13.5.3)。从基类引入赋值运算符的 using-declaration (7.3.3),其参数类型可能是派生类的复制赋值运算符的类型,不被视为复制赋值运算符的显式声明,并且不抑制派生类复制赋值运算符的隐式声明;由 using 声明引入的运算符被派生类中隐式声明的复制赋值运算符隐藏。

代码中的错误是您的基类声明operator=接受派生类类型的引用。这不会阻止隐式公开声明 operator= 为基础。因此,您的派生类基类仍然是可分配的。尝试将您的不可复制类更改为非模板,这应该足够了:

class Uncopyable
{
  protected:
    Uncopyable() {}
    virtual ~Uncopyable() {}
  private:
    Uncopyable(const Uncopyable &);
    Uncopyable & operator=(const Uncopyable&);
};

One more thing i have just figured in that code: Don't make the destructor of Uncopyable virtual. The reason is, no-one (apart from the derived class itself) can call delete on a pointer to Uncopyable (because 1: the destructor is protected, 2: you derive privately). So it's not the concern of Uncopyable to make the destructor of the derived class implicitly virtual. If the derived class needs to have a virtual destructor, put virtual in there instead, and leave Uncopyables' destructor non-virtual.

于 2008-12-27T10:29:00.670 回答