C ++获取类成员的默认值而不创建新对象

时间:2016-10-18 17:21:21

标签: c++ c++11 default-value static-members

让我们考虑定义:

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并不是一个好主意。

Here 是与C#相似的问题

2 个答案:

答案 0 :(得分:2)

我认为,对你而言,这只是另一种解决方法,但我认为有点(只是一点点)更实用。

如果将默认值保存为静态方法返回的静态const,则可以避免cpp文件中的其他行。

以下示例在模板包装器中执行该技巧(默认值为模板参数,默认值为vaule;仅为了好玩)但模板部分只是为了避免示例中的代码重复

#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;
 }

答案 1 :(得分:1)

我将此解决方案称为解决方法

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;