如何在*.cpp文件中实现静态类成员函数?

158

是否可以在*.cpp文件中实现static类成员函数,而不是在头文件中实现?

所有的static函数都是inline的吗?


4
你能解释一下为什么你无法在cpp文件中实现静态类成员函数吗?是否有错误?通常来说,在哪里实现此类函数并没有限制。 - winterTTr
12
问题可能是因为网络上大多数关于C++静态成员函数的例子/教程都没有单独呈现实现的示例,而是在头文件中声明和定义。至少,在我最喜欢的搜索引擎上查找"C++ static member function"时前六个结果都是这样做的,并且对于初学者如何在单独的文件中实现它们没有进行说明。 - crobar
15
实现时不要重复使用 static 关键字,只在头文件中的类定义中写入 static 关键字即可。 - SomethingSomething
@crobar,你说得对,确实缺乏多文件示例。我曾经为此苦苦挣扎,所以我决定分享以下内容: - Don Mclachlan
7个回答

189

可以。关键是只在头文件中使用static关键字,而不是在源文件中使用!

test.hpp:

class A {
public:
    static int a(int i);  // use `static` here
};

test.cpp:

#include <iostream>
#include "test.hpp"


int A::a(int i) {  // do **not** use `static` here!
    return i + 2;
}

using namespace std;
int main() {
    cout << A::a(4) << endl;
}

它们并不总是内联的,但编译器可以将它们变成内联。


53
尝试这个:
header.hxx:
class CFoo
{
public: 
    static bool IsThisThingOn();
};

class.cxx:

#include "header.hxx"
bool CFoo::IsThisThingOn() // note: no static keyword here
{
    return true;
}

11

helper.hxx

class helper
{
 public: 
   static void fn1 () 
   { /* defined in header itself */ }

   /* fn2 defined in src file helper.cxx */
   static void fn2(); 
};

helper.cxx

#include "helper.hxx"
void helper::fn2()
{
  /* fn2 defined in helper.cxx */
  /* do something */
}

A.cxx

#include "helper.hxx"
A::foo() {
  helper::fn1(); 
  helper::fn2();
}

想要了解更多关于C++如何处理静态函数的信息,请访问:C++中的静态成员函数在多个翻译单元中是否会被复制?

6
在你的头文件中声明 foo.h
class Foo{
    public:
        static void someFunction(params..);
    // other stuff
}

在你的实现文件中,比如说 foo.cpp
#include "foo.h"

void Foo::someFunction(params..){
    // Implementation of someFunction
}

非常重要

在实现文件中实现静态函数时,请确保您的方法签名中不使用static关键字。

祝好运


2

@crobar,你说得对,缺乏多文件示例,因此我决定分享以下内容,希望能帮助其他人:

::::::::::::::
main.cpp
::::::::::::::

#include <iostream>

#include "UseSomething.h"
#include "Something.h"

int main()
{
    UseSomething y;
    std::cout << y.getValue() << '\n';
}

::::::::::::::
Something.h
::::::::::::::

#ifndef SOMETHING_H_
#define SOMETHING_H_

class Something
{
private:
    static int s_value;
public:
    static int getValue() { return s_value; } // static member function
};
#endif

::::::::::::::
Something.cpp
::::::::::::::

#include "Something.h"

int Something::s_value = 1; // initializer

::::::::::::::
UseSomething.h
::::::::::::::

#ifndef USESOMETHING_H_
#define USESOMETHING_H_

class UseSomething
{
public:
    int getValue();
};

#endif

::::::::::::::
UseSomething.cpp
::::::::::::::

#include "UseSomething.h"
#include "Something.h"

int UseSomething::getValue()
{
    return(Something::getValue());
}

2

是的,您可以在*.cpp文件中定义静态成员函数。如果您在头文件中定义它,编译器将默认将其视为内联函数。但是,这并不意味着可执行文件中会存在静态成员函数的多个副本。请参考此帖子了解更多信息: C++中的静态成员函数是否在多个翻译单元中复制?


如果你在类体中定义它,它将自动成为默认值。如果它在类体外的头文件中,最好标记为inlinetemplate,否则链接器会报告多个定义错误。 - Ben Voigt

0

#include指令字面上的意思是“将该文件中的所有数据复制到此处”。因此,当您包含头文件时,它在代码文件中是文本形式存在的,并且其中的所有内容(除了其他指令或宏替换的影响)都将在代码文件(现在称为编译单元或翻译单元)从预处理器模块传递给编译器模块时出现。

这意味着您的静态成员函数的声明和定义实际上一直在同一个文件中...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接