了解零法则

Understanding rule of zero

提问人:galvanize 提问时间:9/13/2015 最后编辑:galvanize 更新时间:9/13/2015 访问量:764

问:

我有一个基类,我不想使派生类可复制。为了使所有内容都明确,我以这种方式实现它:

class A {                                                                     
public:    
    A() = default;                                                                   
    virtual ~A() = default;                                                   
    A(const A&)  = delete;                                                    
    A(const A&&) = delete;                                                    
    A& operator=(const A&)  = delete;                                         
    A& operator=(const A&&) = delete;                                         

    virtual void vFun() = 0;                                                  
};                                                                            

class B : public A {                                                          
public:
    B() = default;                                                                       
    virtual ~B() = default;                                                   
    B(const B&)  = delete;                                                    
    B(const B&&) = delete;                                                    
    B& operator=(const B&)  = delete;                                         
    B& operator=(const B&&) = delete;                                         

    virtual void vFun() override {}                                           
};

这是做这些事情的正确方法吗?根据我的知识和我所读到的内容,答案是肯定的,但我想在将其引入生产系统之前确定一下。


编辑

总结一下: 1) 几乎总是移动运算符不应被删除。那是因为“有无穷无尽的东西需要可移动性”。 2)对于抽象基类,允许编译器生成特殊的成员函数,并在存在这种必要性时将删除移动到派生类中是更安全的。

C++ C++11 零法则

评论

4赞 The Paramagnetic Croissant 9/13/2015
移动构造函数应采用而不是 .A &&const A &&
2赞 Emil Laine 9/13/2015
您还删除了移动构造函数和移动分配器,您是否意味着除了不可复制之外,还使类不可移动?顺便说一句,可能不是你想要的const T&&
1赞 Puppy 9/13/2015
您不想让派生类可复制,但是..然后你删除移动运算符?
0赞 galvanize 9/13/2015
是的,我删除了 const,在思考了一段时间后,默认移动构造函数是有意义的。
1赞 Marco A. 9/13/2015
1)在发布答案时不要完全重新编辑问题 2)在不知道你的班级是否涉及所有权和/或它应该做什么的情况下,很难客观地回答,只能发布观察结果

答:

6赞 Puppy 9/13/2015 #1

不,这是完全不正确的。

首先,在你试图使派生类不可复制的过程中,你已经使它不可移动,这使得它几乎毫无用处。

其次,A根本没有理由不可复制。如果需要,每个派生类都可以使自己不可复制。A 已经是抽象的,不能被切片,所以没有理由让 A 不可复制。

评论

1赞 Emil Laine 9/13/2015
您能详细说明一下为什么不可移动性使它几乎毫无用处吗?
0赞 Puppy 9/13/2015
因为有无穷无尽的东西需要可移动性?比如容器、算法等。
0赞 Emil Laine 9/13/2015
很好,但你并不总是需要将你的类与容器和算法一起使用,而且这个类仍然可以被认为是有用的。
0赞 Marco A. 9/13/2015
问题很宽泛,但我对此投赞成票,因为它提出了一些好的观点。
0赞 galvanize 9/13/2015
“不,这是完全不正确的”。在某些情况下,这种实施会奏效。