为什么会有人宣布构造保护? 我知道,构造函数声明为private不容许他们在堆栈创建的目的。
Answer 1:
当一个类(意为)一个抽象类,一个受保护的构造是完全正确的。 在这种情况下,你不想从类实例化的对象,但只用它来继承。
还有其他使用情况下,如当一组特定的结构参数应限于派生类。
Answer 2:
一个用途是工厂模式
Answer 3:
当有不能由构造完全保证施工要求非公共构造函数是有用的。 举例来说,如果一个初始化方法需要调用构造函数之后,或者如果对象需要自身的一些容器/经理对象登记,这必须在构造函数外完成。 通过限制访问的构造和只提供一个工厂方法,可以确保用户接收任何实例将履行其所有保障。 这通常也被用来实现一个Singleton,这真的只是一个保障类可以(也只会有一个实例)。
之所以提出保护,构造函数,而不是私人的,是一样的使受保护的,而不是私人的任何其他方法或字段:以便它可以由孩子继承。 也许你想在基类,它返回到派生类的实例引用公共,非虚拟工厂方法; 派生类显然想访问父构造函数,但你还是不希望自己的工厂以外的地方创建它们。
Answer 4:
受保护的构造方法可以用来制造类有效抽象的时候没有它的方法是纯虚。
这不是在C ++的观点比较抽象,因为友元类仍然可以使用它没有覆盖,但你必须申报这些。
Answer 5:
受保护的构造意味着只有派生成员可以构造使用构造方法的类(和衍生的实例)的实例。 这听起来有点鸡和蛋的,但实现类的工厂时,有时是有用的。
Answer 6:
对于工厂方法有副作用的。
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。 请注意,如果你要使用的构造是不是默认的,你必须隐藏默认了。
Answer 7:
为了让子类使用构造函数不应该直接一个初始化程序访问。
Answer 8:
你可以用它来限制可以创建它,例如类:
class Level
{
private:
Level();
¨Level();
friend class LevelManager;
};
它可以创建它的一个实例唯一类是LevelManager类,所以你将永远知道级别的实例是在LevelManager创建。
Answer 9:
一个使用受保护的构造是落实CRTP模式,见下面的代码:
#include <iostream>
#include <assert.h>
template <class T>
class ComparableMixin {
public:
bool operator !=(ComparableMixin &other) {
return ~(*static_cast<T*>(this) == static_cast<T&>(other));
}
bool operator <(ComparableMixin &other) {
return ((*(this) != other) && (*static_cast<T*>(this) <= static_cast<T&>(other)));
}
bool operator >(ComparableMixin &other) {
return ~(*static_cast<T*>(this) <= static_cast<T&>(other));
}
bool operator >=(ComparableMixin &other) {
return ((*static_cast<T*>(this) == static_cast<T&>(other)) || (*(this) > other));
}
protected:
ComparableMixin() {}
};
class Integer: public ComparableMixin<Integer> {
public:
Integer(int i) {
this->i = i;
}
int i;
bool operator <=(Integer &other) {
return (this->i <= other.i);
}
bool operator ==(Integer &other) {
return (this->i == other.i);
}
};
int main() {
Integer i(0) ;
Integer j(1) ;
//ComparableMixin<Integer> c; //compilation error!
assert (i < j );
assert (i != j);
assert (j > i);
assert (j >= i);
return 0;
}