在类的构造函数中不能初始化(可以在类的构造函数中对静态数据成员进行初始化)

本文目录
- 可以在类的构造函数中对静态数据成员进行初始化
- 为什么静态函数初始化不能在构造函数中进行
- C++问题求解,在类中为什么不能给数据成员初始化值:
- 类声明中的初始化
- C++中类的构造函数的隐式初始化和显示初始化怎么理解
- java为什么将类中的构造函数设为private,默认构造函数就不能初始化对象了呢
- 不要在构造函数中初始化任何变量”为什么
可以在类的构造函数中对静态数据成员进行初始化
这个我觉得是不可以的,静态变量是属于所有对象共有的,应该是独立初始化,不能在构造函数中初始化!如果这样做的话, 那如果这个静态变量的值已经发生了改变,又声明另一个对象时,那静态变量的值难道还有重新在进行一个初始化??????所以我认为静态变量不能在构造函数中初始化!你可以编一个程序试试!!
为什么静态函数初始化不能在构造函数中进行
你说的是静态成员变量吧?静态成员变量应该在类外部(最好是对应的cpp文件中)直接进行初始化。这是语言规定,因为静态成员变量是所有实例共享的,所以不能在构造函数中初始化。
C++问题求解,在类中为什么不能给数据成员初始化值:
因为类只是定义的类型, 还没有实例化,也就是没有定义类的对象(变量), 没法存储
你可以在初始化列表里进行初始化 , 而构造函数的函数体之内赋值的话, 是在初始化后,
-------------
至于定义成static的, 这是静态的, 所有对象共享一个副本, 程序开始执行就初始化了, 就算没有定义对象, 也有它的实例, 能直接使用 A::static_a = xxx;
类声明中的初始化
声明中不能初始化,因为声明的时候并没有分配存储空间的。可以在构造函数中初始化,因为调用构造函数后表示给这个对象分配了空间
public class Test {
public static void main(String args){
ForTest f=new ForTest(10);
System.out.println(f.getA());
f.a=100;//你的意思是这样吗? 类的成员在声明时同时初使化?
System.out.println(f.getA());
}
}
class ForTest{
int a=3;//成员变量声明的同时初始化.
public ForTest(int a){
this.a=a;
}
public int getA(){
return a;
}
}
就你的提问来看,有些概念你还不是很清晰(问得有些让人听不懂).如果不是我所说的上面这样,请你贴出代码来提问问题.
C++中类的构造函数的隐式初始化和显示初始化怎么理解
可以看一下下面的这个例子:
有一个类的构造函数为: A(int i) : m_i(i){}
显示初始化的:
A abc(200);//显式初始化,直接调用构造函数
A a = A(1);//直接调用构造函数,没有临时对象,作用域结束时析构
A* e = new A(2);//直接调用构造函数,使用delete时析构
A d(*e);//显式初始化,调用拷贝构造函数,作用域结束时析构
隐式初始化的
A c = 0;//这是一种隐式初始化,直接调用构造函数,没有临时对象。不要看到=号就以为要用拷贝构造函数。
A b = a;//用一个对象隐式初始化另一对象,调用拷贝构造函数,作用域结束时析构
显示初始化的就是 你直接调用构造函数或拷贝构造函数,函数写什么样,你就怎么样调用。
而隐式的 就是 不是函数调用的方式,但是后面操作的依然是构造函数或拷贝构造函数,只是看起来不明显而已
java为什么将类中的构造函数设为private,默认构造函数就不能初始化对象了呢
创建类对象就会调用构造函数,private是只能本类成员调用,你创建的对象根本没法调用private,肯定不能初始化啊
比如说单例模式,就不能在外部来创建类对象,而是通过一个方法在类本身来创建,看下下面例子就明白了
public class Cat {
public static Cat cat;
private Cat() {}
public static Cat getInstance() {//这样就可以保证整个程序最多只能有一个cat对象
if(cat == null) { //如果cat为null,就创建cat对象,否则不创建,直接在下面返回已经存在的cat
cat = new Cat();
}
return cat;
}
}
不要在构造函数中初始化任何变量”为什么
首先你应该明确这个规定的限制范围:只是针对MonoBehaviour的派生类,为什么,因为其他的类就是正常的C#类,你在里面写Awake方法,就是个普通的叫Awake的方法,并不会被自动调用。
原因也很简单,MonoBehaviour代表的是一个组件,在Unity3D里面组件是必须依附于GameObject存在的,对于这种类你永远都不会使用new来创建一个实例,而是使用AddComponent或GetComponent方法来获取。Unity3D的开发人员并不想让你知道这个类是具体什么时候new出来的,你只要关心我想要的时候能够拿到一个引用就可以了。
你引用的这条限制,在我理解来看实际是说:“MonoBehaviour的生命周期并不是从构造函数开始的,而是从Awake开始的”。在构造函数中初始化变量,一般来说目的是将类的状态设置到一个“初始状态”,对于MonoBehaviour来说,你相当于在这个类的生命周期之外设定了它的状态,此时这个代码就是不严谨的,而应该放在Awake里面去。
因此,在我的理解来看,你应该避免做的是在构造函数里设定任何跟类的内部状态有关的事情。举例来说,如果我在做一个计数器,有一个count变量,这个变量就明显是内部状态,count=0这句话就应该放在Awake中。另外,程序不是一个类组成的,在实际工程中,有时候一个类的状态依赖于其他类的状态,你举例的GUI.Button方法可以看做设定了GUI类的内部状态,这个代码也不应该放在构造函数中(这个例子不好之处在于GUI类的方法只能在onGUI中调用,不能在任何其他地方,包括Awake中使用,如果换用一个其它全局变量可能更能说明问题)
另一方面,我们可以做一些不牵扯到类的内部状态的事情,举个例子:
class A{
public int count;
public int price;
public string name;}class AComponent : MonoBehaviour{
A inner;
public int Count {get{return inner.count;} set{ inner.count = value;}}
public int Price {...}
public String Name {...}
public AComponent(){
inner = new A();
}
public Awake(){
Count=0;
Price=10;
Name="Something";
}}
在这样一个类的构造方法中我创建了一个A对象给了inner,原因在于我这个类的内部状态并不在inner本身,而是在于inner的内部状态,此时创建出来inner不是为了设定状态,而是为了让几个属性永远都能用而已。实际状态设定还是在Awake中。
当然这个new也可以写在Awake中,因为毕竟实际用到这几个属性的时候Awake应该是已经调用过了,但这两者还是有略微的区别,就是何时创建这个对象的问题。如果你做过手游,应该会知道手机环境上new一个东西的效率并不是很高(由于这个东西不是临时对象,所以不讨论GC问题),写在构造函数里会在资源加载时调用,写在Awake里会在第一次使用(例如它依附的GameObject第一次变成active)时调用。
假设这个A类占用很大内存,甚至可能会出现内存不够的crash,那么这两者就有区别了,写在new中,这个申请内存会在资源加载时,此时游戏大概会有一个loading的界面,卡一点是可以接受的,如果crash掉了,也会给用户一个明显的暗示就是内存不够导致的crash,是不是关一些后台程序再来试试。而放在Awake中,可能发生的是用户第一次触发某个功能,放某个技能,就会卡一下,如果crash掉了,那就是在说我这个功能没做好,所以崩了,这种体验比起上一种是要差一些的。
结论:大部分情况下把所有的初始化写在Awake里就行,写在构造函数里并不是完全没有应用场景,但比较少见,是一种具体问题具体分析的优化策略,写的时候需要脑子清楚,知道自己为什么要这么写。

更多文章:
全球新冠肺炎疫情背景下航运发展(盐田港复苏日志:半年历劫从“低谷”到“爆仓” 疫情之后巨轮如何越洋航行)
2026年9月7日 17:10
matlab求解带字母参数方程组(我想matlab求一个关于x,y的方程组 ab c d f e h m n 都是参数)
2026年9月7日 16:30
oracle中的循环语句(下面哪个不是oracle程序设计中的循环语句 a for)
2026年9月7日 15:30
电脑里2个系统怎么删除一个(电脑开机显示有两个系统,如何删除一个)
2026年9月7日 12:20
scrollthrough意思(“scroll”是什么意思)
2026年9月7日 08:00
怎么激活keygen(注册机如何激活cad2008一个简单激活cad2008的方法)
2026年9月7日 06:30





