我似乎对static
关键字在C ++中的工作原理有一些误解;具体来说,我需要通过以下代码了解问题:
#include <iostream>
struct A{
int a;
A(int ain) : a(ain) { }
A() : a(1) { }
static A getA()
{
return A(2);
}
};
struct B
{
static A a = A::getA();
};
int main() {
std::cout << B::a.a << std::endl;
}
如果static
按预期工作,上面的代码示例将打印2
并正常退出 - 相反,我得到以下编译器错误消息:
g++ -c -o syntax.o syntax.cpp
syntax.cpp:17:21: error: ‘A::getA()’ cannot appear in a constant-expression
static A a = A::getA();
^
syntax.cpp:17:26: error: a function call cannot appear in a constant-expression
static A a = A::getA();
^
syntax.cpp:17:26: error: invalid in-class initialization of static data member of non-integral type ‘A’
syntax.cpp:17:26: error: initializer invalid for static member with constructor
syntax.cpp:17:26: error: (an out of class initialization is required)
syntax.cpp:17:26: error: ‘B::a’ cannot be initialized by a non-constant expression when being declared
make: *** [syntax.o] Error 1
我阅读了错误消息,并且我发现有一些关于static
的内容我还没有理解,但我发现很难确定是什么。这可能是因为我在Java和C#等语言中做了相当多的工作,这些语言也有static
关键字,但显然它的工作方式不同。
请有人向我解释为何上述代码无效?
答案 0 :(得分:4)
静态会员功能
有两种方法可以调用给定T
的静态成员函数;
您使用T
在所述类型operator.
的实例上调用它(就像您在变量上调用任何其他成员函数一样)。 / p>
法律架构
struct Obj {
static void func () {
/* ... */
}
};
下面的两个片段都在func
内调用静态成员函数Obj
。
Obj a; a.func ();
Obj::func ();
ILLEGAL CONSTRUCTS
Obj a;
Obj.func (); // illegal, `Obj` is a type and not an instance
a ::func (); // illegal, `a` is an instance of `Obj`, not a type
静态数据成员
static
数据成员用于声明在给定类型的每个实例之间共享的变量。
在问题中提供的代码段中,您尝试初始化类型为a
的静态数据成员A
,其中包含已更正的值A::getA ()
。这是不允许的,因为尝试初始化static
数据成员而不使其constexpr
是用于类内初始化的非法构造。
struct B {
static A a = A::getA(); // illegal, `static A a` is not `constexpr`
};
可以在此处找到有关静态数据成员的类内初始化的更多信息:
答案 1 :(得分:3)
有两个问题。首先,语法A.getA()
是错误的:.
语法用于访问实例的成员。您不能使用它通过类型访问成员。要使用.
运算符,您必须创建A
的实例,并通过该实例调用getA()
。但这没有任何意义。所以你需要做的是使用类范围分辨率调用方法,即A::getA()
。这是第一个问题。
第二个是你不能在声明点定义一个非const,非整数的静态成员。您必须将声明与定义分开。后者应该只在一个翻译单元中,这意味着将它放在一个.cpp
文件中:
标题文件:
struct B
{
static A a; // declaration
};
实施档案
A B::a = A::getA(); // definition
答案 2 :(得分:1)
您使用语法调用实例函数,您需要使用scope resolution operator ::
语法:
A::getA();