C++ 受保护构造函数的实际用途是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1057221/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What are practical uses of a protected constructor?
提问by Amol Gawai
Why would anyone declare a constructor protected? I know that constructors are declared private for the purpose of not allowing their creation on stack.
为什么有人会声明构造函数受保护?我知道构造函数被声明为私有是为了不允许它们在堆栈上创建。
回答by Henk Holterman
When a class is (intended as) an abstract class, a protected constructor is exactly right. In that situation you don't want objects to be instantiated from the class but only use it to inherit from.
当一个类是(打算作为)抽象类时,受保护的构造函数是完全正确的。在这种情况下,您不希望从类中实例化对象,而只使用它来继承。
There are other uses cases, like when a certain set of construction parameters should be limited to derived classes.
还有其他用例,比如当一组特定的构造参数应该限于派生类时。
回答by Nick Lewis
Non-public constructors are useful when there are construction requirements that cannot be guaranteed solely by the constructor. For instance, if an initialization method needs to be called right after the constructor, or if the object needs to register itself with some container/manager object, this must be done outside the constructor. By limiting access to the constructor and providing only a factory method, you can ensure that any instance a user receives will fulfill all of its guarantees. This is also commonly used to implement a Singleton, which is really just another guarantee the class makes (that there will only be a single instance).
当存在不能由构造函数单独保证的构造要求时,非公共构造函数很有用。例如,如果需要在构造函数之后立即调用初始化方法,或者如果对象需要向某个容器/管理器对象注册自己,则必须在构造函数之外完成。通过限制对构造函数的访问并仅提供工厂方法,您可以确保用户收到的任何实例都将履行其所有保证。这也常用于实现单例,这实际上只是类所做的另一个保证(只有一个实例)。
The reason for making the constructor protected, rather than private, is the same as for making any other method or field protected instead of private: so that it can be inherited by children. Perhaps you want a public, non-virtual factory method in the base class, which returns references to instances of the derived classes; the derived classes obviously want access to the parent constructors, but you still don't want to be creating them outside of your factory.
将构造函数设为protected 而不是private 的原因与将任何其他方法或字段设为protected 而不是private 的原因相同:以便它可以被子代继承。也许您需要基类中的公共非虚拟工厂方法,它返回对派生类实例的引用;派生类显然想要访问父构造函数,但您仍然不想在工厂之外创建它们。
回答by Guidobot
A protected constructor can be used to make a class effectively abstract when none of its methods are pure-virtual.
当一个类的方法都不是纯虚拟的时,受保护的构造函数可用于使该类有效地抽象。
It is not quite abstract in the C++ sense since friend classes can still use it without overriding, but then you would have to declare these.
它在 C++ 意义上不是很抽象,因为友元类仍然可以使用它而无需覆盖,但是你必须声明这些。
回答by Umair Ahmed
one use could be factory patterns
一种用途可能是工厂模式
回答by Umair Ahmed
A protected constructor means that only derived members can construct instances of the class (and derived instances) using that constructor. This sounds a bit chicken-and-egg, but is sometimes useful when implementing class factories.
受保护的构造函数意味着只有派生成员才能使用该构造函数构造类(和派生实例)的实例。这听起来有点生硬,但有时在实现类工厂时很有用。
回答by sean riley
For factory methods with side-effects.
对于有副作用的工厂方法。
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; }
};
This creates instances of the class and guarantees that each of them has a unique incrementing integer id. Note that if the constructor you want to use is not the default, you must hide the default too.
这将创建类的实例并保证它们中的每一个都有一个唯一的递增整数 id。请注意,如果您要使用的构造函数不是默认值,则您也必须隐藏默认值。
回答by Oliver Hanappi
To let a subclass use a constructor that should not be accessible to an instantiator directly.
让子类使用实例化器不能直接访问的构造函数。
回答by Oliver Hanappi
You could use it to limit the classes that could create it, for example:
您可以使用它来限制可以创建它的类,例如:
class Level
{
private:
Level();
¨Level();
friend class LevelManager;
};
The only class that can create an instance of it is the LevelManager class, so you will always know that the Level instance is created in the LevelManager.
唯一可以创建它的实例的类是 LevelManager 类,因此您将始终知道 Level 实例是在 LevelManager 中创建的。
回答by bigdata2
One use of protected constructor is to implement the CRTP pattern, see the code below:
受保护构造函数的一种用途是实现 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;
}