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;
}
};
我需要更新变量m
的值。因此,我使用static int
数据类型。但接下来的错误来了。使用int
而不是static int
工作正常。为什么static int
会出错?
3条答案
按热度按时间wn9m85ua1#
Bjarne Stroustrup在这里解释说:
类通常在头文件中声明,并且头文件通常包含在许多转换单元中。然而,为了避免复杂的链接器规则,C要求每个对象都有唯一的定义。如果C允许在类内定义需要作为对象存储在内存中的实体,那么这条规则就被打破了。
正如Stroustrup所说,每个类都需要一个唯一的定义。现在,正如我们所知,静态成员直接与它们的类相关联。现在考虑两种情况:
static
成员也是constant
,那么它的初始化是允许内联的,因为编译器可以进行自己的优化,并将此成员视为编译时常量,因为它可以保证其值永远不会更改。因此,由于此成员的值是固定的,因此与此成员关联的类的定义也是固定的。因此,允许内联初始化。static
成员不是常量。然后它的值可以在程序执行期间稍后更改。因此,编译器不能对此成员进行编译时优化。因此,为了防止在加载类时尝试初始化此类成员时可能出现的复杂性,不允许对此类成员进行内联初始化。**PS:**当我第一次听到这个概念时,我也很困惑,因为它不符合程序员所期望的正交性原则。正交性的原理将说明,由于我们可以合并
int
和static
;以及int
和const
,我们应该能够以类似的方式写入static const int
和static int
。但是这里的情况是一种情况的例子,其中语言的开发者必须给予语言用户的正交性,以换取编译过程的简单性。看看正交性here的概念
6qftjkof2#
回答OP的问题“为什么”
很好但是
不是:
简而言之:用
static
作为数据成员的前缀从根本上改变了它的含义。没有
static
,成员变量是类的一部分,每个示例将为该成员变量提供单独的存储。**使用
static
**时,成员变量只有类的作用域,但只有一个全局存储。分别地,初始化也具有不同的含义。
对于非静态成员变量,它提供了构造函数可以使用(或重写)的默认初始化。
示例演示:
输出:
Live Demo on coliru
对于
static
成员变量,初始化将是危险的。假设一个类在一个包含多次的头文件中声明,这将导致违反One Definition Rule。在以前,通常在头文件中 * 声明 *
static
成员变量,但在.cpp
文件(代表translation unit)中 * 定义 * 它。示例:
solution.h
:solution.cc
:Live Demo on coliru
从C++17开始,有了一个新的替代方案--使用关键字
inline
。来自cppreference.com -静态成员-静态数据成员
静态数据成员可以内联声明。内联静态数据成员可以在类定义中定义,并且可以指定初始化式。它不需要类外定义
示例:
solution.h
:Live Demo on coliru
优点是不需要
.cpp
文件,即实际上,X1 M11 N1 X可以被提供为仅报头源。5w9g7ksd3#
你可以做的是在你调用相应函数的地方,首先,初始化一个int,然后通过地址将该int传递给类方法。相应地编辑类方法定义。