根据'静态'上的this链接C ++中的关键字:
static关键字仅用于静态声明 成员,在类定义中,但没有定义 那个静态成员。
为什么成员函数定义中禁止使用static关键字?我确实理解将某个功能重新声明为“静态”功能。在其定义上是多余的。但是在编译函数定义时使用它应该是无害的,因为它不会导致任何歧义。那么为什么编译器会禁止它?
答案 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的方式有关。例如,如果您将源文件中的函数标记为“静态”,那么这是无意义的,因为该信息无法传送到编译对象和共享库。为什么允许呢?相反,它只会引起歧义。
出于同样的原因,默认参数必须进入标题,而不是源文件。因为源文件(包含实现),不能将默认参数信息携带到编译对象。