c++类中的静态变量初始化的问题

时间:2022-12-12 16:44:24
最近在学习C++遇到一个问题如下:
#include<iostream>
using namespace std;

class Y
{
private:
static int i;
public:
Y(int a):i(a){;}/*该行提示错误。cannot initialize static class data via constructor*/
int a;
void set(int);
int get();
};


int  Y::i = 10;

int Y::get()
{
return i;
}

void Y::set(int aa)
{
i  = aa;
}

int main()
{


Y yy;
yy.set(20);
cout<<yy.get()<<endl;
return 0;
}

但是
#include<iostream>
using namespace std;

class Y
{
private:
static int i;
public:
Y(int a){i = a;}
int a;
void set(int);
int get();
};


int  Y::i = 10;

int Y::get()
{
return i;
}

void Y::set(int aa)
{
i  = aa;
}

int main()
{


Y yy(0);
yy.set(20);
cout<<yy.get()<<endl;
return 0;
}
就编译通过了。修改处为蓝色内容
所以请教一下。第一种初始化为什么不行啊??
另外,第二种编译通过的情况下。注释掉红色语句,也编译不过。请教!!

17 个解决方案

#1


第二个注释掉的那个语句为
int  Y::i = 10; 
没显示出来。呵呵

#2


大家好像都睡觉了。。。
先说一下第二个问题。就是注释掉 int  Y::i = 10;之后编译不过。
感觉是类中的静态变量好像是独立于类对象的实体而存在的。也就是说在类对象没有被定义之前,它就已经被分配内存空间了。所以,如果不进行赋值。那么,该静态变量就只是被声明而没有被定义。所以类对象在定义时就会找不到该变量。所以编译提示 unresolved external symbol "private: static int Y::i"
好像是没定义的意思。

同时,我有做了一个实验,就是直接在main函数中定义静态变量:
static int a;
int b = a;
编译通过了。这就说明,在函数或者全局的静态变量和类中的静态变量,编译器并不是同等对待的。

感觉有点眉目了,期待大家讨论,把这个问题搞清楚。。

#3


静态变量是在class外定义的


int Y::i = 某个值



静态变量跟构造函数没关系

构造函数是为了构造对象而定义的,而静态变量是 一个类的变量,而不是不是类的对象的变量,所以自然不应该在用于构造对象的构造函数中初始化

一就是说如果你的静态变量需要用构造函数来构造,那就证明i不应该是个静态变量。而应该是一般变量

#4


第一种编译不过是因为静态变量只能初始化一次。i(a)  和 i = a 是不一样的。i(a)是初始化,
对于基类和const 变量必须这样做。
i = a 是赋值

#5


那么晚,你不睡觉,干吗呢?还在提问题,真强.

#6


静态变量属于类所有,不属于对象,他的初始化是在类外面   如 int  y::i=12;
你的第一种在构造函数初始化列表中初始化这种格式是const 和对基类初始化时使用的

#7


我也在学C++,佩服楼主,那么晚了还在学习....容许我卑微的敬礼!

#8


不能用一个变量来初始化i,静态变量的初始化必须是一个确定的值

#9


static成员必须在类定义体外定义.不可用构造函数初始化,应该在定义时初始化.const static可在类定义体内初始化

class Y 

private: 
static int i; //类内声明
static const int j=20;//ok,const static可在类定义体内初始化
public: 
//Y(int a):i(a){;}/*该行提示错误。cannot initialize static class data via constructor*/ 
int a; 
void set(int); 
int get(); 
}; 
int Y::i=10;//类外定义时初始化


main()
.....





#10


规定就是这样,楼主记住就ok了

#11


静态变量在类体外初始化啊。。

#12


跑到cpp文件构造函数实现上一行加上
int ClassA::i = 5;

就万事大吉了!具体的楼上的都说得很清楚了!

#13


类中
static 成员在类外初始化
const 成员在类的构造函数初始化列表中初始化
static const /const static 成员可以在类中初始化(实际上是申明)也可以不初始化,同时需要在类外定义

欢迎指正!
// 很多人问,答者聊聊,整理一下,以供参考
class MyTestClass
{
public:
    MyTestClass() : m_ciInt(1), m_csStr("MyStr")  // const成员变量,在ctor参数列表中初始化
    {}
public:
    const int m_ciInt;
    const String m_csStr;
    static int m_siInt;
    static String m_ssStr;
    const static int m_csiInt;
    const static String m_cssStr;
};
int MyTestClass::m_siInt = 1; // static成员变量,在外部定义
String MyTestClass::m_ssStr = "MyStr"; // static成员变量,在外部定义
const int MyTestClass::m_csiInt = 1;  // const static/static const成员变量,在外部定义
const String MyTestClass::m_cssStr = "MyStr"; // const static/static const成员变量,在外部定义 

#14


Y::i=..;

在类定义外,显式赋值就可以了。

#15


引用 3 楼 superspring 的回复:
静态变量是在class外定义的

C/C++ codeint Y::i= 某个值

静态变量跟构造函数没关系

构造函数是为了构造对象而定义的,而静态变量是 一个类的变量,而不是不是类的对象的变量,所以自然不应该在用于构造对象的构造函数中初始化

一就是说如果你的静态变量需要用构造函数来构造,那就证明i不应该是个静态变量。而应该是一般变量

多谢,一语中的啦,呵呵。
而且从只从语法上分析:如果没有int  Y::i = 10;那么所有的代码中都没有定义。因为类中的static变量是独立于类对象以外的。不会再在类对象定义时一起分配内存。。

#16


引用 4 楼 wanyuzhen 的回复:
第一种编译不过是因为静态变量只能初始化一次。i(a)  和 i = a 是不一样的。i(a)是初始化,
对于基类和const 变量必须这样做。
i = a 是赋值

恩,构造函数初始化列表适用于类中的const对象和类的继承。。呵呵,类的继承还没看到。。继续看。。
多谢了!

#17


引用 15 楼 wuruogeng 的回复:
引用 3 楼 superspring 的回复:
静态变量是在class外定义的

C/C++ codeint Y::i= 某个值

静态变量跟构造函数没关系

构造函数是为了构造对象而定义的,而静态变量是 一个类的变量,而不是不是类的对象的变量,所以自然不应该在用于构造对象的构造函数中初始化

一就是说如果你的静态变量需要用构造函数来构造,那就证明i不应该是个静态变量。而应该是一……

楼主搞透了这个没?随便问下:
#include <iostream>
using namespace std;

class A{
     static int m;
     int n;
public:
     A(int m,int n)
         {
                 this->m = m;
                 this->n = n;
         }
     void print()
         { 
                 cout << m << "---" << n << endl;
         }
};
int A::m ;   //这个没有赋予初值啊?
void main()
{
    A a1(3,4);
    A a2(5,6);
    a1.print();
    a2.print();

#1


第二个注释掉的那个语句为
int  Y::i = 10; 
没显示出来。呵呵

#2


大家好像都睡觉了。。。
先说一下第二个问题。就是注释掉 int  Y::i = 10;之后编译不过。
感觉是类中的静态变量好像是独立于类对象的实体而存在的。也就是说在类对象没有被定义之前,它就已经被分配内存空间了。所以,如果不进行赋值。那么,该静态变量就只是被声明而没有被定义。所以类对象在定义时就会找不到该变量。所以编译提示 unresolved external symbol "private: static int Y::i"
好像是没定义的意思。

同时,我有做了一个实验,就是直接在main函数中定义静态变量:
static int a;
int b = a;
编译通过了。这就说明,在函数或者全局的静态变量和类中的静态变量,编译器并不是同等对待的。

感觉有点眉目了,期待大家讨论,把这个问题搞清楚。。

#3


静态变量是在class外定义的


int Y::i = 某个值



静态变量跟构造函数没关系

构造函数是为了构造对象而定义的,而静态变量是 一个类的变量,而不是不是类的对象的变量,所以自然不应该在用于构造对象的构造函数中初始化

一就是说如果你的静态变量需要用构造函数来构造,那就证明i不应该是个静态变量。而应该是一般变量

#4


第一种编译不过是因为静态变量只能初始化一次。i(a)  和 i = a 是不一样的。i(a)是初始化,
对于基类和const 变量必须这样做。
i = a 是赋值

#5


那么晚,你不睡觉,干吗呢?还在提问题,真强.

#6


静态变量属于类所有,不属于对象,他的初始化是在类外面   如 int  y::i=12;
你的第一种在构造函数初始化列表中初始化这种格式是const 和对基类初始化时使用的

#7


我也在学C++,佩服楼主,那么晚了还在学习....容许我卑微的敬礼!

#8


不能用一个变量来初始化i,静态变量的初始化必须是一个确定的值

#9


static成员必须在类定义体外定义.不可用构造函数初始化,应该在定义时初始化.const static可在类定义体内初始化

class Y 

private: 
static int i; //类内声明
static const int j=20;//ok,const static可在类定义体内初始化
public: 
//Y(int a):i(a){;}/*该行提示错误。cannot initialize static class data via constructor*/ 
int a; 
void set(int); 
int get(); 
}; 
int Y::i=10;//类外定义时初始化


main()
.....





#10


规定就是这样,楼主记住就ok了

#11


静态变量在类体外初始化啊。。

#12


跑到cpp文件构造函数实现上一行加上
int ClassA::i = 5;

就万事大吉了!具体的楼上的都说得很清楚了!

#13


类中
static 成员在类外初始化
const 成员在类的构造函数初始化列表中初始化
static const /const static 成员可以在类中初始化(实际上是申明)也可以不初始化,同时需要在类外定义

欢迎指正!
// 很多人问,答者聊聊,整理一下,以供参考
class MyTestClass
{
public:
    MyTestClass() : m_ciInt(1), m_csStr("MyStr")  // const成员变量,在ctor参数列表中初始化
    {}
public:
    const int m_ciInt;
    const String m_csStr;
    static int m_siInt;
    static String m_ssStr;
    const static int m_csiInt;
    const static String m_cssStr;
};
int MyTestClass::m_siInt = 1; // static成员变量,在外部定义
String MyTestClass::m_ssStr = "MyStr"; // static成员变量,在外部定义
const int MyTestClass::m_csiInt = 1;  // const static/static const成员变量,在外部定义
const String MyTestClass::m_cssStr = "MyStr"; // const static/static const成员变量,在外部定义 

#14


Y::i=..;

在类定义外,显式赋值就可以了。

#15


引用 3 楼 superspring 的回复:
静态变量是在class外定义的

C/C++ codeint Y::i= 某个值

静态变量跟构造函数没关系

构造函数是为了构造对象而定义的,而静态变量是 一个类的变量,而不是不是类的对象的变量,所以自然不应该在用于构造对象的构造函数中初始化

一就是说如果你的静态变量需要用构造函数来构造,那就证明i不应该是个静态变量。而应该是一般变量

多谢,一语中的啦,呵呵。
而且从只从语法上分析:如果没有int  Y::i = 10;那么所有的代码中都没有定义。因为类中的static变量是独立于类对象以外的。不会再在类对象定义时一起分配内存。。

#16


引用 4 楼 wanyuzhen 的回复:
第一种编译不过是因为静态变量只能初始化一次。i(a)  和 i = a 是不一样的。i(a)是初始化,
对于基类和const 变量必须这样做。
i = a 是赋值

恩,构造函数初始化列表适用于类中的const对象和类的继承。。呵呵,类的继承还没看到。。继续看。。
多谢了!

#17


引用 15 楼 wuruogeng 的回复:
引用 3 楼 superspring 的回复:
静态变量是在class外定义的

C/C++ codeint Y::i= 某个值

静态变量跟构造函数没关系

构造函数是为了构造对象而定义的,而静态变量是 一个类的变量,而不是不是类的对象的变量,所以自然不应该在用于构造对象的构造函数中初始化

一就是说如果你的静态变量需要用构造函数来构造,那就证明i不应该是个静态变量。而应该是一……

楼主搞透了这个没?随便问下:
#include <iostream>
using namespace std;

class A{
     static int m;
     int n;
public:
     A(int m,int n)
         {
                 this->m = m;
                 this->n = n;
         }
     void print()
         { 
                 cout << m << "---" << n << endl;
         }
};
int A::m ;   //这个没有赋予初值啊?
void main()
{
    A a1(3,4);
    A a2(5,6);
    a1.print();
    a2.print();