2008-12-27 34 views
1

我有几个不想被复制的类,其中一些类具有指针数据成员。为了使这些类不可复制我私有继承,下面的类模板:当使用“不可复制”类时使GCC警告无效

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&) 

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

+0

你使用的是什么版本的g ++? – codelogic 2008-12-27 10:44:57

+0

我正在使用g ++ 4.3 – Kazade 2008-12-27 12:00:38

回答

9

C++说

因为拷贝赋值运算符 隐含的类中声明,如果不是由用户声明,基类的拷贝赋值运算符总是 由派生类的拷贝赋值运算符隐藏(13.5.3)。使用声明(7.3.3)将带有来自基类的 带有参数类型的赋值运算符(可能是派生类的复制赋值 运算符)的赋值运算符不被视为复制赋值的显式声明运算符和 不抑制派生类复制赋值运算符的隐式声明;由使用声明引入的运算符被派生类中的隐式声明的复制赋值运算符隐藏。

在代码中的错误是,你的基类声明operator=接受型的派生类的参考。这不会阻止隐式公开声明=对于基数。因此,您的派生类您的基类仍然可分配。试着改变你的不可复制类到非模板,这应该足够了:

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

还有一件事我刚刚想通代码:不要让不可复制的虚拟的析构函数。原因是,没有人(除派生类本身之外)可以调用指向Uncopyable的指针删除(因为1:析构函数受保护,2:您私下导出)。因此,Uncopyable并不关心让隐式虚拟派生类的析构函数。如果派生类需要有一个虚拟析构函数,那么在其中放入虚拟对象,并让Uncopyables的析构函数非虚拟。

相关问题