为什么静态成员函数定义没有关键字' static'?

时间:2017-07-24 10:17:46

标签: c++ static

根据'静态'上的this链接C ++中的关键字:

  

static关键字仅用于静态声明   成员,在类定义中,但没有定义   那个静态成员

为什么成员函数定义中禁止使用static关键字?我确实理解将某个功能重新声明为“静态”功能。在其定义上是多余的。但是在编译函数定义时使用它应该是无害的,因为它不会导致任何歧义。那么为什么编译器会禁止它?

4 个答案:

答案 0 :(得分:17)

有歧义好吧。同样的定义根本不需要成员函数。

考虑一下:

namespace foo {
    static void bar();
}

static void foo::bar() {

}
使用相同的链接说明符定义

foo::bar 必需

但是,对于成员函数,static不是链接说明符。如果允许,foo::bar定义的正确性将非常上下文取决于foo。实际上,禁用static可以减轻编译器的负担。

将其扩展到一般成员,而不仅仅是成员函数,这是一致的问题。

答案 1 :(得分:3)

关键是,#include <type_traits> template<typename F, F f> struct S1 {}; template<typename F, F f> struct S2 {}; template<typename F, F f> using BaseType = typename std::conditional<std::is_member_function_pointer<F>::value, S1<F, f>, S2<F, f>>::type; template<typename Class, typename... Args> Class * call_constructor(Args... args) { return new Class(args...); } template<class Class, typename... Args> struct Constructor : BaseType<Class *(*)(Args...), call_constructor<Class, Args...>> { using ReturnType = Class *; }; int main() {} 有几个非常不同的含义:

static

此处class Foo { static void bar(); } 关键字表示函数static与类bar相关联,但未在Foo的实例上调用。 Foo的含义与面向对象密切相关。但是,声明

static

意味着非常不同:这意味着static void bar(); 仅在文件范围内可见,不能直接从其他编译单元调用该函数。

你看,如果你在类声明中说bar,那么以后将函数限制为文件范围没有任何意义。如果你有一个static函数(带有文件范围),那么将它作为公共头文件中类定义的一部分发布是没有意义的。 这两个含义是如此不同,以至于它们实际上相互排斥。

static有更多不同的含义:

static

是另一种含义,与

相似但不完全相同
void bar() {
    static int hiddenGlobal = 42;
}

编程时,所有语境中的词语并不总是相同的含义。

答案 2 :(得分:0)

狂野猜测,但如果定义具有静态,则可以将其解释为C语义中的​​文件范围变量。

答案 3 :(得分:0)

您必须了解声明和实施之间的区别,这将回答您的问题:

声明:在编译程序之前是如何看到C ++函数和方法的。它放在头文件(.h文件)中。

实现:编译器如何将声明链接到二进制代码中的实际任务。实现可以动态编译(从源文件,.cpp或.cxx或.cc),也可以编译(从共享库或目标文件)。

现在回到你的问题,当你声明某些东西是静态的时,它与实现无关,而是与编译器在编译代码时看到decleration的方式有关。例如,如果您将源文件中的函数标记为“静态”,那么这是无意义的,因为该信息无法传送到编译对象和共享库。为什么允许呢?相反,它只会引起歧义。

出于同样的原因,默认参数必须进入标题,而不是源文件。因为源文件(包含实现),不能将默认参数信息携带到编译对象。