【问题标题】:Define static method in source-file with declaration in header-file in C++在源文件中定义静态方法,并在 C++ 中的头文件中声明
【发布时间】:2011-08-24 05:51:00
【问题描述】:

我在使用 C++ 中的静态方法时遇到了一点问题

示例.h:

class IC_Utility {
public:
    IC_Utility();
    ~IC_Utility();

    std::string CP_PStringToString( const unsigned char *outString );
    void CP_StringToPString( std::string& inString, unsigned char *outString, short inMaxLength );
    static void CP_StringToPString( std::string& inString, unsigned char *outString);
    void CP_StringToPString( FxString& inString, FxUChar *outString);

};

示例.cpp:

static void IC_Utility::CP_StringToPString(std::string& inString, unsigned char *outString)
{
    short       length = inString.length();

   if( outString != NULL )
    {
        if( length >= 1 )
            CPLAT::CP_Utility::CP_CopyMemory( inString.c_str(), &outString[ 1 ], length );

            outString[ 0 ] = length;
    }
}

我想拨打这样的电话:

IC_Utility::CP_StringToPString(directoryNameString, directoryName );

但我得到一个错误:

error: cannot declare member function 'static void IC_Utility::CP_StringToPString(std::string&, unsigned char*)' to have static linkage

我不明白为什么我不能这样做。谁能帮我理解为什么以及如何实现我想要的?

【问题讨论】:

  • 首先,您应该删除 .cpp 文件中的 static 关键字。 C++ 不允许这样做。
  • @Fezvez:或者,将其替换为 /* static */。我喜欢在 .h 和 .cpp 文件中使用相同的修饰符和默认参数。
  • TL;DR:在头文件.h中保留static,意思是“附加到类,而不是任何对象”,删除.cpp文件中的static,它有在这里你不想要的不同含义。

标签: c++ static-linking


【解决方案1】:

删除方法定义中的static 关键字。将其保留在您的类定义中。

static关键字放在.cpp文件中表示某个函数有静态链接,即。它只能从同一文件中的其他函数访问。

【讨论】:

  • 啊,知道了,方法定义中的static 意味着只有该类中的其他方法可以访问该静态方法,该类之外的其他方法不能访问。
  • 不是其他类方法,而是.cpp文件中的其他函数。无论如何,你不应该在 C++ 中这样做。如果您希望 C++ 函数具有内部链接,则应考虑将其放置在某个匿名命名空间中。在 .cpp 文件中使用 static 只是为了向后兼容 C。
  • 只是为了好奇......如果我直接在类中(在.h文件中)定义一个静态类成员,我怎么能使用静态链接?
  • 你不能。这样做是没有意义的,因为将程序链接在一起会导致出现未解析的外部。
【解决方案2】:

关键字staticvirtual 不应在定义中重复。它们只能在类声明中使用。

【讨论】:

    【解决方案3】:

    你不需要在函数定义中有static

    【讨论】:

      【解决方案4】:

      可能最好的做法是“像标准库那样做”。即:全部内联,全部在标题中。

      // in the header
      namespase my_namespace {
      
         class my_standard_named_class final {
      public:
               static void standard_declared_defined_method () {
                  // even the comment is standard
               }
         } ;
      
      } // namespase my_namespace 
      
      

      就这么简单……

      【讨论】:

        【解决方案5】:

        静态成员函数必须引用该类的静态变量。所以在你的情况下,

        static void CP_StringToPString( std::string& inString, unsigned char *outString);
        

        由于您的成员函数CP_StringToPstring 是静态的,因此该函数中的参数inStringoutString 也应声明为静态。

        静态成员函数不引用它正在处理的对象,但您声明的变量引用其当前对象,因此它返回错误。

        您可以从成员函数中删除静态或添加静态,同时将用于成员函数的参数也声明为静态。

        【讨论】:

        • inString 和 outString 是静态函数的参数。他们不是班级成员。无需将它们转换为静态。
        • 这根本不正确。您可以将非静态参数放在静态成员函数中。但是对于类成员,您只能访问/修改函数中的静态成员。
        猜你喜欢
        • 2013-08-04
        • 2017-06-22
        • 1970-01-01
        • 2016-06-08
        • 1970-01-01
        • 2010-12-10
        • 2012-04-05
        • 2016-12-19
        相关资源
        最近更新 更多