C++ 何时使用静态成员函数?

C++ 何时使用静态成员函数?,c++,function,static,C++,Function,Static,可能的重复项: 何时在C++中使用静态成员函数是合适的?请给我一个现实世界的例子。一个常见的例子(在现实世界的例子中)是在创建线程时。公共线程API(POSIX/pthreads、Boost和Win32 CreateThread)都需要特定的签名。在成员函数中获得该签名的唯一方法是将函数设置为静态。我误读了您的问题,并在适合使用静态函数时给出了答案 你指的是静态成员函数。下面是一个何时使用静态成员函数的示例—将线程调用包装在类中,以便线程可以访问类…: static unsigned WIN

可能的重复项:


<>何时在C++中使用静态成员函数是合适的?请给我一个现实世界的例子。

一个常见的例子(在现实世界的例子中)是在创建线程时。公共线程API(POSIX/pthreads、Boost和Win32 CreateThread)都需要特定的签名。在成员函数中获得该签名的唯一方法是将函数设置为静态。

我误读了您的问题,并在适合使用静态函数时给出了答案

你指的是静态成员函数。下面是一个何时使用静态成员函数的示例—将线程调用包装在类中,以便线程可以访问类…:

static unsigned WINAPI ArchiveAgent::LogMsgPump(PVOID pData)
{
    ArchiveAgent* pSmith = reinterpret_cast<ArchiveAgent*>(pData);

    if( pSmith )
        pSmith->LogMsgPump();
    else
        return -1;

    return 0;
}

unsigned WINAPI ArchiveAgent::LogMsgPump()
{
    CoInitializeEx(NULL, COINIT_MULTITHREADED);

    // ....

    CoUninitialize();
    return 0;
}
static unsigned WINAPI ArchiveAgent::LogMsgPump(PVOID pData)
{
ArchiveAgent*pSmith=重新解释铸件(pData);
if(pSmith)
pSmith->LogMsgPump();
其他的
返回-1;
返回0;
}
未签名的WINAPI ArchiveAgent::LogMsgPump()
{
CoInitializeX(空,Conit_多线程);
// ....
coninitialize();
返回0;
}
这是我对简单的旧静态函数的回答。。 我使用静态函数,如果该函数属于一个类是没有意义的

我通常倾向于将这些函数添加到自定义名称空间。以下静态函数示例是我称之为ShellUtils的命名空间的一部分:

static HRESULT CreateFolder( CString & sPath )
{
// create the destination folder if it doesn't already exist

HRESULT hr      = S_OK;
DWORD   dwError = 0;

if( sPath.GetLength() == 0 || sPath.GetLength() < 2 )                   
    return E_UNEXPECTED;

if( GetFileAttributes( (LPCWSTR) sPath ) == INVALID_FILE_ATTRIBUTES )
{           
    dwError = SHCreateDirectoryEx(NULL, (LPCWSTR)sPath, NULL);

    if (dwError != ERROR_SUCCESS && dwError != ERROR_FILE_EXISTS && dwError != ERROR_ALREADY_EXISTS)
        hr = HRESULT_FROM_WIN32(dwError);
}

return hr;
静态HRESULT CreateFolder(CString&sPath)
{
//如果目标文件夹不存在,请创建该文件夹
HRESULT hr=S_正常;
DWORD dwError=0;
if(sPath.GetLength()==0 | | sPath.GetLength()<2)
意外返回E_;
if(GetFileAttributes((LPCWSTR)sPath)=无效的文件属性)
{           
dwError=SHCreateDirectoryEx(NULL,(LPCWSTR)sPath,NULL);
如果(dwError!=错误\u成功&&dwError!=错误\u文件\u存在&&dwError!=错误\u已存在)
hr=HRESULT\u FROM\u WIN32(dwError);
}
返回人力资源;

}

您可能希望在不实例化对象的情况下使用函数。另外,如果从另一个静态函数调用该函数,则该函数必须是静态的。

请查找名为singleton的设计模式。简而言之,这是限制对象创建的一种方法。因此,创建对象的唯一方法是调用一个静态的C++成员函数。

一个典型的例子可以是一个单独的类,其中静态GestStand()方法返回类的SnutLon实例。p>
class Singleton
{
    static Singleton instance;

    private Singleton()
    {
    }

    static Singleton & GetInstance()
    {
      if(instance == null)
        instance = new Singleton();

      return instance;
    }
}

静态成员函数的良好使用:

  • 元编程。现实世界的例子是模板std::char\u traits。所有成员函数都是静态的
  • 将其设置为静态成员函数可以让它访问类的私有成员,尽管这里有一个朋友也足够了
  • 因此,受保护的静态成员函数只能由类及其派生的类访问
注意,最后一种情况适用于受保护的静态成员函数,但不适用于私有函数。在后一种情况下,您只需将其放入类的编译单元中,将其作为实现细节隐藏起来。对于一个受保护的对象,尽管您希望它是可见的,尽管是以受限的方式

其中一个典型的例子是“欺骗”缺乏友谊的传承

class B
{
   friend class A;
   // lots of private stuff
};

class A
{
protected:
   static void callsSomePrivateMembers( B& b );
};

class AChild : public A
{
   void foo( B& b );
}

void AChild::foo( B& b )
{
      // AChild does not have private access to B as friendship is not inherited
      // but I do have access to protected members of A including the static ones

    callsSomePrivateMembers( b ); // get to call them through a back-door
}

当您因为需要访问类的内部结构而无法使用自由函数时,自然会使用它。最典型的例子是构建器函数,如下所示。Foo的构造函数是私有的,以确保它不是用builder函数以外的任何方式构造的

#include <iostream>

class Foo {
public:
  static Foo* createFoo() {return new Foo();}
private: 
  Foo() {}
};

int main() {
  //Foo nonBuiltFoo; //wont compile
  Foo* freshFoo = Foo::createFoo();
  delete freshFoo;
  return 0;
}
#包括
福班{
公众:
静态Foo*createFoo(){返回新的Foo();}
私人:
Foo(){}
};
int main(){
//Foo非编译Foo;//不会编译
Foo*freshFoo=Foo::createFoo();
删除freshFoo;
返回0;
}

前面提到的Singleton模式是该模式的一个典型用法。当您不必访问类的受保护和私有部分时,不需要静态成员函数(可以使用自由函数),但也有一些在类的域内使用静态成员函数,但在单个实例上使用该函数不受限制/不符合逻辑。

我编辑了这个问题,因为我认为作者只是指“OOP”或面向对象编程。对不起,这不是oops,而是OOP,谢谢Moo Juice实际上我想链接的是Mahesh做的,而不是我实际做的。但是我仍然投票赞成关闭…-1:他问的是静态成员函数。一般不是静态函数。错过了那个,会修改答案的!我觉得不值得记下我的名字!“一个自由函数也可以。”马修:在某些情况下,是的。但是,如果您正在创建一个线程包装器类,情况就不是这样了。我不明白为什么,您能给出一个代码示例吗?(抱歉…:/)@Matthieu:看看MFC的CWinThread,这是一个很好的例子。+1表示元编程,但我没有得到“需要私有访问的成员函数”。这不是常规成员函数所做的吗?我的意思是,使其成为静态成员函数可以访问类的私有区域。最好使用类的函数级静态实例来实现单例模式。请参阅“Meyers Singleton”(Meyers Singleton)()想添加…只有在了解其优点和缺点后才建议使用Singleton…除了少数例外情况外,Singleton通常会产生更多问题…想想..线程问题..破坏Singleton…为什么(第二点)?我承认我不工作在C++中,所以可能会漏掉它的复杂之处,但是至少在C和java中,静态函数可以使用实例成员,这是需要的。C++在这方面有什么不同吗?“你可能想使用没有实例化对象的函数”——它似乎是唯一回答实际问题的答案!