构造和析构函数定义为私有场景
一、背景
在C++中,当我们在堆或栈上创建一个对象的时候,系统会自动调用对象的构造函数;当对象声明周期结束的时候,系统又会自动调用对象的析构函数。其实,我们在阅读其他项目的时候,也会发现有些类定义中,会将构造和析构函数申明为私有;客户端在这正常情况下无法创建该类的对象(不考虑使用相关的方式)。如下定义的类:
1 class CoreUtil 2 { 3 public: 4 static void Func1(){ 5 std::cout << "Func1.\n"; 6 } 7 8 private: 9 CoreUtil() { 10 std::cout << "CoreUtil::ctor\n"; 11 } 12 ~CoreUtil() { 13 std::cout << "CoreUtil::dtor\n"; 14 } 15 }; 16 17 int main() 18 { 19 CoreUtil coreUtil; 20 }
编译的时候会直接提示无法访问构造函数:
二、什么时候私有化构造/析构函数
如果在客户端调用的方式如下,编译和运行都正常:
1 int main() 2 { 3 CoreUtil::Func1(); 4 }
这就是构造函数私有化的一种使用场景。下面是我列举的已知的三种使用场景:
- 类无任何属性或属性全部为静态,方法全部为静态,外部访问无需构造对象,也就无需析构函数。比如工具类:
1 class CoreUtil 2 { 3 public: 4 static void Func1(){ 5 std::cout << "Func1.\n"; 6 } 7 8 private: 9 CoreUtil() { 10 std::cout << "CoreUtil::ctor\n"; 11 } 12 ~CoreUtil() { 13 std::cout << "CoreUtil::dtor\n"; 14 } 15 };
- 定义的类只提供给友元类内部使用:
1 class TestA { 2 public: 3 void SetValue(int value) { 4 _value = value; 5 } 6 int GetValue() const { 7 return _value; 8 } 9 private: 10 friend class TestB; 11 TestA() { 12 std::cout << "TestA::ctor\n"; 13 } 14 15 ~TestA() { 16 std::cout << "TestA::dtor\n"; 17 } 18 19 int _value; 20 }; 21 22 class TestB { 23 public: 24 TestB() { 25 std::cout << "TestB::ctor\n"; 26 } 27 ~TestB() { 28 std::cout << "TestB::dtor\n"; 29 } 30 void Init() { 31 _testA.SetValue(10); 32 } 33 int GetTestAValue() const { 34 return _testA.GetValue(); 35 } 36 private: 37 TestA _testA; 38 };
- 单例模式中的单例类,客户端全局只需要一个对象,且构造由该类提供公共静态方法构造并且不能被拷贝:
1 class Singleton { 2 public: 3 static Singleton& Instance() { 4 static Singleton instance; 5 return instance; 6 } 7 void setValue(int value) { 8 _value = value; 9 } 10 int GetValue() const { 11 return _value; 12 } 13 private: 14 Singleton() { 15 std::cout << "Singleton::ctor\n"; 16 } 17 ~Singleton() { 18 std::cout << "Singleton::dtor\n"; 19 } 20 21 Singleton(const Singleton&) = delete; 22 Singleton& operator= (const Singleton&) = delete; 23 24 int _value; 25 };
上面客户端调用代码如下:
1 int main() 2 { 3 // 1 4 CoreUtil::Func1(); 5 std::cout << "==================================\n"; 6 // 2 7 TestB testB; 8 testB.Init(); 9 std::cout << "value : " << testB.GetTestAValue() << "\n"; 10 std::cout << "==================================\n"; 11 // 3 12 Singleton::Instance().setValue(20); 13 std::cout << "value : " << Singleton::Instance().GetValue() << "\n"; 14 }
如果遇到其他使用场景,再同步更新到博客。https://chromium.googlesource.com/chromium/src/media/+/master/audio/win/core_audio_util_win.h 中的类就是第一种场景。