c++在不创建新对象的情况下获取类成员的默认值

C++ get default value of class member without creating new object

本文关键字:情况下 获取 默认值 成员 对象 创建 新对象 c++      更新时间:2023-10-16

让我们考虑一下定义:

struct ClassWithMember
{
    int myIntMember = 10;
}

我希望获得myIntMember的默认值,但不要创建类的另一个实例

// IMPOSSIBLE int myInt = ClassWithMember::myIntMember;  
// MUST AVOID int myInt = ClassWithMember().myIntMember;

我知道变通办法,但不喜欢它:

struct ClassWithMember
{
    static const int myIntMember_DEFAULT = 10;
    int myIntMember = myIntMember_DEFAULT;
}
int myInt = ClassWithMember::myIntMember_DEFAULT;

因为需要额外的行。我不能像static const int *const INTEGER11_DEFAULT = 0x100088855;那样定义内联静态指针,这样的指针必须在.cpp文件中定义,在.hpp中只是声明。我的许多类都是头文件,所以为这个值创建多余的.cpp不是一个好主意。

这里是c#

的类似问题

我想,对你来说,这只是另一种变通方法,但我认为这更实用一点。

如果您将默认值保存为静态方法返回的静态const,则可以避免在cpp文件中添加额外的行。

下面的例子在模板包装器中完成了这个技巧(使用默认值作为模板参数,默认值为;只是为了好玩),但模板部分只是为了避免示例

中的代码重复。
#include <iostream>
template <typename T, T defTpl = T{}>
struct wrapperWithDef
 {
   static T getDefVal ()
    { static T const def { defTpl }; return def; }
   T myTMember { getDefVal() };
 };
int main()
 {
   wrapperWithDef<int>          wi;
   wrapperWithDef<long, 3L>     wl;
   wrapperWithDef<int *>        wp;
   // print "0, 3, (nil)" (clang++) or "0, 3, 0" (g++)
   std::cout << wi.myTMember << ", " << wl.myTMember << ", "
      << wp.myTMember << std::endl;
   // print "5, (nil), 1" (clang++) or "5, 0, 1" (g++)
   std::cout << wrapperWithDef<unsigned, 5U>::getDefVal() << ", "
      << wrapperWithDef<long *>::getDefVal() << ", "
      << wrapperWithDef<bool, true>::getDefVal() << std::endl;
   return 0;
 }

我把这个解决方案叫做workaround

struct ClassWithMember
{
    static const int myIntMember_DEFAULT = 10;
    int myIntMember = myIntMember_DEFAULT;
}
int myInt = ClassWithMember::myIntMember_DEFAULT;

对于指针,它看起来更复杂

//.hpp
struct ClassWithMember
{
    static AnotherClass* const myMember_DEFAULT;  //=X; Assignment not allowed
    AnotherClass* myMember = myMember_DEFAULT;
}
//.cpp
AnotherClass* const MyNamespace::ClassWithMember::myMember_DEFAULT = pAnotherInstance;
//usage
auto *my = ClassWithMember::myMember_DEFAULT;