问题可能缺少一些信息,但我真正想知道的是,当构造函数需要是私有的时候,拥有公共析构函数是否符合C ++规则?
将构造函数设为私有但析构函数设为公共的做法有很多实际用途。
你可以使用这种模式来:
上面我提到,您可以使用私有构造函数和析构函数来实现几个设计模式。接下来就是如何实现...
引用计数
在对象中使用私有析构函数有助于引用计数系统。这使得开发人员能够更好地控制对象的生命周期。
class MyReferenceObject
{
public:
static MyReferenceObject* Create()
{
return new MyReferenceObject();
}
void retain()
{
m_ref_count++;
}
void release()
{
m_ref_count--;
if (m_ref_count <= 0)
{
// Perform any resource/sub object cleanup.
// Delete myself.
delete this; // Dangerous example but demonstrates the principle.
}
}
private:
int m_ref_count;
MyReferenceObject()
{
m_ref_count = 1;
}
~MyReferenceObject() { }
}
int main()
{
new MyReferenceObject(); // Illegal.
MyReferenceObject object; // Illegal, cannot be made on stack as destructor is private.
MyReferenceObject* object = MyReferenceObject::Create(); // Creates a new instance of 'MyReferenceObject' with reference count.
object->retain(); // Reference count of 2.
object->release(); // Reference count of 1.
object->release(); // Reference count of 0, object deletes itself from the heap.
}
MyReferenceObject
会删除自己,在此处查看需要考虑的事项清单。
单例模式
一个单例类中的私有构造函数和析构函数的主要优点是强制用户只能按照代码设计的方式使用它。无法创建一个流氓单例对象(因为它在编译时被强制执行),用户也无法删除单例实例(同样是在编译时被强制执行)。class MySingleton
{
public:
MySingleton* Instance()
{
static MySingleton* instance = NULL;
if (!instance)
{
instance = new MySingleton();
}
return instance;
}
private:
MySingleton() { }
~MySingleton() { }
}
int main()
{
new MySingleton(); // Illegal
delete MySingleton::Instance(); // Illegal.
}
看看代码几乎不可能被误用。在编译时强制执行MySingleton
的正确使用,从而确保开发人员必须按预期使用MySingleton
。
工厂模式
在工厂设计模式中使用私有构造函数是一种重要机制,以强制仅使用工厂创建对象。
例如:
class MyFactoryObject
{
public:
protected:
friend class MyFactory; // Allows the object factory to create instances of MyFactoryObject
MyFactoryObject() {} // Can only be created by itself or a friend class (MyFactory).
}
class MyFactory
{
public:
static MyFactoryObject* MakeObject()
{
// You can perform any MyFactoryObject specific initialisation here and it will carry through to wherever the factory method is invoked.
return new MyFactoryObject();
}
}
int main()
{
new MyFactoryObject(); // Illegal.
MyFactory::MakeObject(); // Legal, enforces the developer to make MyFactoryObject only through MyFactory.
}
MyFactoryObject
的创建隐藏在开发者背后。你可以使用工厂方法来执行任何MyFactoryObject
的初始化(例如:设置GUID,注册到数据库),并且无论在何处使用工厂方法,该初始化代码也将被执行。首先:析构函数可以是私有的。
当要求构造函数为私有时,拥有公共析构函数是否符合C++规则?
在C++中完全可行。事实上,一个很好的例子就是单例模式,其中构造函数是私有的,而析构函数是公共的。
singleton
时,析构函数都被设为私有的,这激起了更多的疑问和问题。 - Sankalp倒序。
析构函数是否需要公开,以便在继承期间可以进行调用,还是代码中存在错误?
实际上,为了使继承起作用,析构函数至少应该是protected
。如果您从具有私有析构函数的类继承,则无法为派生类生成析构函数,这实际上会防止实例化(您仍然可以使用static
方法和属性)。
这种声明有什么用途?
请注意,即使构造函数是私有的,如果没有进一步指示,该类也具有(默认生成的)公共复制构造函数和复制赋值运算符。这种模式经常出现在:
命名构造函数惯用法的示例:
class Angle {
public:
static Angle FromDegrees(double d);
static Angle FromRadian(double d);
private:
Angle(double x): _value(x) {}
double _value;
};
由于不确定 x
应该用度数还是弧度(或其他单位),构造函数被设置为 private
,并提供了 命名方法。这样,使用方法可以明确单位:
Angle a = Angle::FromDegrees(360);
如果您想防止创建类的多个实例,则可以将构造函数设置为私有。这样,您就可以控制实例的创建而不是销毁。因此,析构函数可以是公共的。
我脑海中有一个例子,假设您想将类实例数量限制为0或1。 例如,对于某些单例类,您希望应用程序可以临时销毁对象以减少内存使用。为了实现这一点,构造函数将是私有的,但析构函数将是公共的。请参见以下代码片段。
class SingletoneBigMemoryConsumer
{
private:
SingletoneBigMemoryConsumer()
{
// Allocate a lot of resource here.
}
public:
static SingletoneBigMemoryConsumer* getInstance()
{
if (instance != NULL)
return instance;
else
return new SingletoneBigMemoryConsumer();
}
~SingletoneBigMemoryConsumer()
{
// release the allocated resource.
instance = NULL;
}
private:
// data memeber.
static SingletoneBigMemoryConsumer* instance;
}
//Usage.
SingletoneBigMemoryConsumer* obj = SingletoneBigMemoryConsumer::getInstance();
// You cannot create more SingletoneBigMemoryConsumer here.
// After 1 seconds usage, delete it to reduce memory usage.
delete obj;
// You can create an new one when needed later