2011-02-07 125 views
10

可能显示的文件:
Where would you use a friend function vs a static function?
C++: static member functions何时使用静态成员函数?

时候适合使用C++中的静态成员函数?请给我一个真实世界的例子。

+2

什么是'oops`标签? – Maxpm 2011-02-07 12:16:20

+2

我编辑的问题,因为我认为作者只是意味着“面向对象”,或面向对象的编程。 – 2011-02-07 12:18:35

+1

http://stackoverflow.com/questions/4723143/c-static-member-functions – Mahesh 2011-02-07 12:20:25

回答

11

好用途:

  • 元编程。真实世界的例子是模板std :: char_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 
} 
4

一个常见的例子,你会发现(在现实世界的例子)是当你创建一个线程。公共线程API(POSIX/pthreads,Boost和Win32 CreateThread)都需要特定的签名。在成员函数中获得签名的唯一方法是使函数静态。

+0

自由功能可以很好地工作。 – 2011-02-07 12:42:13

2

我误解了你的问题,并回答了何时适合使用静态函数。

你的意思是静态成员函数。这里的时候使用一个静态成员函数的例子 - 包装一个线程调用一个类里面,让你的线程可以访问你的类...:

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

这是我对普通的旧静态函数答案.. 我使用静态函数,它对于该函数属于一个类没有意义。

我通常倾向于将这些函数添加到自定义名称空间。下面的静态函数样本是命名空间,我称之为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; 

}

3

您可能需要使用的功能,而不实例化一个对象。另外,如果函数是从另一个静态函数调用的,它必须是静态的。

2

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

2

一个典型的例子可以是一个单例类,其中静态GetInstance()方法返回该类的单例实例。静态成员函数

class Singleton 
{ 
    static Singleton instance; 

    private Singleton() 
    { 
    } 

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

     return instance; 
    } 
} 
6

使用它的自然地方是当你不能使用免费函数,因为你需要访问该类的内部。这个最典型的例子是一个构建器函数,如下所示。 Foo的构造函数是私有的,以确保它不是用构建器函数以任何其他方式构建的。

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

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