class Solution {
public:
static int m=INT_MIN; // it shows error: non-const static data member must
be initialized out of line.(why?)
using "int m=INT_MIN" is fine.
int func(TreeNode*root){
if(root==NULL){
return 0;
}
int l=max(func(root->left),0);
int r=max(func(root->right),0);
m=max(l+r+root->val,m);
return max(l,r)+root->val;
}
int maxPathSum(TreeNode* root) {
if(root==NULL)
{
return 0;
}
m=INT_MIN;
int x=func(root);
return m;
}
};
Run Code Online (Sandbox Code Playgroud)
我需要更新 variable 的值m。因此我使用static int数据类型。但是下面的错误来了。使用int而不是static int工作正常。但是为什么会static int报错呢?

Sch*_*eff 21
回答OP的问题为什么
\nclass Solution {\n public:\n int m = INT_MIN;\n};\nRun Code Online (Sandbox Code Playgroud)\n很好但是
\nclass Solution {\n public:\n static int m = INT_MIN;\n};\nRun Code Online (Sandbox Code Playgroud)\n不是:
\n简而言之:给数据成员添加前缀从static根本上改变了它的含义。
如果没有static,成员变量是类的一部分,每个实例都会为此成员变量提供单独的存储。
使用 时static,成员变量仅具有类的范围,但只有一个全局存储。
分别来说,初始化也有不同的含义。
\n对于非静态成员变量,它提供了构造函数可以使用(或覆盖)的默认初始化。
\n举例演示:
\n#include <iostream>\n\nenum ArgCase1 { Case1 };\nenum ArgCase2 { Case2 };\n\nclass Solution {\n public:\n int m = 123;\n \n Solution() = default; // will use m(123) implicitly\n Solution(ArgCase1) { } // will use m(123) implicitly\n Solution(ArgCase2): m(456) { } // default of m ignored\n};\n\n#define DEBUG(...) std::cout << #__VA_ARGS__ << ";\\n"; __VA_ARGS__ \n\nint main()\n{\n DEBUG(Solution sol);\n std::cout << "sol.m: " << sol.m << \'\\n\';\n DEBUG(Solution sol1(Case1));\n std::cout << "sol1.m: " << sol1.m << \'\\n\';\n DEBUG(Solution sol2(Case2));\n std::cout << "sol2.m: " << sol2.m << \'\\n\';\n}\nRun Code Online (Sandbox Code Playgroud)\n输出:
\nclass Solution {\n public:\n int m = INT_MIN;\n};\nRun Code Online (Sandbox Code Playgroud)\n\n对于static成员变量来说,初始化是很危险的。假设一个类在多次包含的标头中声明,这将导致违反“单一定义规则”。
以前,通常在标头中声明成员变量,但在文件(代表翻译单元)中定义它。static.cpp
示例:
\nsolution.h:
#ifndef SOLUTION_H\n#define SOLUTION_H\n\nclass Solution {\n public:\n static int m;\n};\n\n#endif // SOLUTION_H\nRun Code Online (Sandbox Code Playgroud)\nsolution.cc:
// header of this module:\n#include "solution.h"\n\nint Solution::m = 123;\nRun Code Online (Sandbox Code Playgroud)\n\n从 C++17 开始,可以使用关键字 \xe2\x80\x93 来使用新的替代方案inline。
来自cppreference.com \xe2\x80\x93 静态成员 \xe2\x80\x93 静态数据成员
\n\n\n静态数据成员可以声明为内联。内联静态数据成员可以在类定义中定义,并且可以指定初始值设定项。它不需要类外定义
\n
例子:
\nsolution.h:
#ifndef SOLUTION_H\n#define SOLUTION_H\n\nclass Solution {\n public:\n inline static int m = 123;\n};\n\n#endif // SOLUTION_H\nRun Code Online (Sandbox Code Playgroud)\n\n优点是不需要.cpp为此文件,即它class Solution可以作为仅标头源提供。
类通常在头文件中声明,而头文件通常包含在许多翻译单元中。但是,为了避免复杂的链接器规则,C++ 要求每个对象都有唯一的定义。如果 C++ 允许需要作为对象存储在内存中的实体的类内定义,那么这条规则就会被打破。
正如 Stroustrup 所说,每个类都需要一个唯一的定义。现在,我们知道静态成员直接与其类相关联。现在考虑两种情况:
该static成员还constant,那么它的初始化直列允许的,因为编译器可以做出自己的优化,并因为它保证了它的价值不会改变对待这个成员作为一个编译时间常数。因此,由于该成员的值是固定的,因此该成员所关联的类的定义也是固定的。因此,允许内联初始化。
该static构件是不恒定的。然后它的值可以在程序执行期间更改。因此,编译器无法对这个成员进行编译时优化。因此,为了防止在加载类时尝试初始化此类成员时可能出现的复杂情况,不允许对此类成员进行内联初始化。
PS:第一次听说这个概念的时候,我也很困惑,因为它不符合程序员所希望的正交性原则。正交性原则将说明,由于我们可以组合int和static;和int和const,我们应该能够编写static const int和static int以类似的方式。但这里的这种情况是一种情况的例子,语言的开发人员必须放弃语言用户的正交性,以换取编译过程的简单性。
在这里查看正交性的概念