2009-06-29 107 views

回答

73

当一个类是(打算作为)一个抽象类时,受保护的构造函数是完全正确的。在这种情况下,你不希望从类中实例化对象,而只是使用它来继承。

还有其他用例,例如某些构造参数应限制为派生类。

11

一个用途是使用构造工厂模式

6

甲受保护的构造意味着只有派生成员可以构造类(和衍生的实例)的实例。这听起来有点鸡与鸡蛋,但在实施班级工厂时有时很有用。

+3

从技术上讲,这只适用于所有ctors都受到保护的情况。 – MSalters 2009-06-29 09:09:42

+1

朋友类也可以调用受保护的构造函数(不仅仅是派生类)。 – 2013-09-29 03:48:32

+0

...并且调用受保护的构造函数的朋友类的使用将是对象具有常量(由构造函数设置)的成员的情况,但需要公开,但绝不会被其他公共访问设置,从而保证该对象不会在其他地方创建,因此数据也不会在其他地方被修改。 – osirisgothra 2014-03-02 17:37:53

3

让子类使用不应该直接访问实例化器的构造函数。

3

你可以用它来限制可以创建它的类,例如:

class Level 
{ 
private: 

Level(); 
¨Level(); 

friend class LevelManager; 
}; 

,它可以创建它的一个实例中唯一的类是LevelManager类,所以你将永远知道水平实例在LevelManager中创建。

7

非公开构造函数在有构造函数无法保证的构造要求时非常有用。例如,如果需要在构造函数之后立即调用初始化方法,或者如果对象需要向某个容器/管理器对象注册自己,则必须在构造函数之外完成此操作。通过限制对构造函数的访问并仅提供工厂方法,您可以确保用户收到的任何实例都将履行其所有保证。这也通常用于实现一个单例,这实际上是类的另一个保证(只有一个实例)。

使构造函数受到保护(而不是私有)的原因与使其他方法或字段受保护而不是私有相同:因此它可以由子项继承。也许你想在基类中使用公共的非虚拟工厂方法,它返回对派生类实例的引用;派生类显然需要访问父构造函数,但您仍然不想在工厂外创建它们。

2

对于具有副作用的工厂方法。

class mine { 

    private: 
    mine() {}; 

    protected: 
    mine(int id) : m_id(id) {}; 

    int m_id; 
    static int m_count; 

    public: 
    static mine* CreateOneOfMe() { 
     return mine(m_count++); 
    } 

    int GetId() { return m_id; } 

}; 

这创建了类的实例并确保它们中的每一个都具有唯一的递增整数id。请注意,如果您要使用的构造函数不是默认构造函数,则您也必须隐藏默认构造函数。

5

受保护的构造函数可用于在没有任何方法是纯虚拟时有效地抽象类。

它在C++中并不是很抽象,因为朋友类仍然可以使用它而不会覆盖,但是接下来你将不得不声明这些。

相关问题