请教C++中对象的初始化和构造函数问题:

程序源码如下:
#include <iostream>
using namespace std;

class Stu
{
public:
int x,y;
Stu();
};
Stu::Stu()
{
cout<<"stu constructor"<<endl;
}
int main()
{
Stu stu1;
//Stu stu2={1,2};
return 0;
}
这段程序没有问题,但是,如果我把main函数的注释语句去掉,程序就编译不通过,错误提示:error C2552: 'stu2' : non-aggregates cannot be initialized with initializer list。但是如果把类Stu中的构造函数Stu()定义连同构造函数的定义体一起去掉,则Stu stu2={1,2};又可以编译通过,请高人指点迷津,先谢谢了。
对不起,我刚才没有写清楚,我的目的不是让大家改正程序,而是让大家解释这样出错的原因。我想可能就是对象的初始化和构造函数的关系问题,我认为并非对象的初始化一定要调用构造函数,举个例子:
如:
#include <iostream>
using namespace std;

class Stu
{
public:
int x,y;
Stu();

};
Stu::Stu()
{
cout<<"stu constructor"<<endl;
}

int main()
{
Stu stu1;
Stu stu2=stu1;
return 0;
}在这段程序中,stu2显然是由拷贝构造函数复制的,而stu2并没有调用类的构造函数。不知道大家理解我的疑问没有,就是想知道Stu stu2={1,2};和Stu stu2=stu1;的区别与联系;

如果没有定义拷贝构造函数,则默认将数据成员对应一一复制,使用的值是=后对象的数据成员值。

之所以出现你说的问题是因为你没有理解构造函数是怎么运行的。 如果自己定义了构造函数,则使用这个函数,否则使用默认构造函数(与拷贝构造函数一样将数据成员对应一一复制)。但是你定义的构造函数只有输出语句,参数也没有默认值,所有会初始化错。
//
我刚才实验了一下,觉得你还是理解的不够深入。你做了例子,编译通过了,却没有看结果怎样。
事实上,有几点需要弄清楚:
一、类不同于c中的结构体,一般不用{ }初始化对象;
MSDN帮助信息:
Compiler Error C2552
'identifier' : non-aggregates cannot be initialized with initializer list
The specified identifier was incorrectly initialized.
An initializer list is needed to initialize the following types:
An array
A class, structure, or union that does not have constructors, private or protected members, base classes, or virtual functions
These types are known as “aggregates.”
你定义的类有构造函数,不满足上面说的条件,所有不能用{ }

二、自定义的构造函数内部如果没有赋值语句的话,即使调用了它,其数据成员x,y也将只会是随机值(把stu2的定义改为Stu stu2(1,2); 并试着输出就知道了)
如果把构造函数改为如下:
Stu(int a=0,int b=0);
{
x=a; y=b;
cout<<"stu constructor"<<endl;
}
并使用Stu stu2(1,2); 定义,则stu1的x,y分别为0,0;stu2的x,y分别为1,2

三、我刚才使用Stu stu2(1,2); 定义,为什么没有用你说的Stu stu2=Stu(1,2);呢?因为在类名后直接加括号的方法会定义一个没有对象名的临时对象,然后把这个临时对象赋给了stu2,这并不是通用的初始化方法(但是正确)。最好用通用的方法。

四、关于隐式类型转换,我查了一下别的书,的确,用=是隐式,用()是显式。说明如下:
class Stu
{explict Stu(int a);
……
};
加上显示声明关键字explict,只能进行显式声明:Stu stu1(3);
如果不加,将可以这样隐式声明:Stu s=3; 这个句子就相当于将3这个整型量转换成了Stu对象,在某些场合,这样的转换是十分危险的,加上explict后将杜绝这种可能性。 相关内容可以查阅“类型转换函数”。
我参考的书是《C++标准程序库》华中科技大学。
另外给点小建议,初学语言和熟悉环境(比方VC++)的过程中,细究语法是有必要的,但是学完继承,派生,虚函数,模板等概念以后,就要着重理解C++面向对象的思想,和用它解决实际问题的思路。

这就是他们的关系,正解
温馨提示:答案为网友推荐,仅供参考
第1个回答  2007-10-24
没有构造函数
定义:
内部定义:
Stu::Stu(int x1, int y1)
{
x = x1;
y = y1;
}
然后main中语句改成:
Stu stu2 = Stu(1,2);
第2个回答  2019-07-03
如果没有定义拷贝构造函数,则默认将数据成员对应一一复制,使用的值是=后对象的数据成员值。
之所以出现你说的问题是因为你没有理解构造函数是怎么运行的。
如果自己定义了构造函数,则使用这个函数,否则使用默认构造函数(与拷贝构造函数一样将数据成员对应一一复制)。但是你定义的构造函数只有输出语句,参数也没有默认值,所有会初始化错。
//
我刚才实验了一下,觉得你还是理解的不够深入。你做了例子,编译通过了,却没有看结果怎样。
事实上,有几点需要弄清楚:
一、类不同于c中的结构体,一般不用{
}初始化对象;
MSDN帮助信息:
Compiler
Error
C2552
'identifier'
:
non-aggregates
cannot
be
initialized
with
initializer
list
The
specified
identifier
was
incorrectly
initialized.
An
initializer
list
is
needed
to
initialize
the
following
types:
An
array
A
class,
structure,
or
union
that
does
not
have
constructors,
private
or
protected
members,
base
classes,
or
virtual
functions
These
types
are
known
as
“aggregates.”
你定义的类有构造函数,不满足上面说的条件,所有不能用{
}
二、自定义的构造函数内部如果没有赋值语句的话,即使调用了它,其数据成员x,y也将只会是随机值(把stu2的定义改为Stu
stu2(1,2);
并试着输出就知道了)
如果把构造函数改为如下:
Stu(int
a=0,int
b=0);
{
x=a;
y=b;
cout<<"stu
constructor"<<endl;
}
并使用Stu
stu2(1,2);
定义,则stu1的x,y分别为0,0;stu2的x,y分别为1,2
三、我刚才使用Stu
stu2(1,2);
定义,为什么没有用你说的Stu
stu2=Stu(1,2);呢?因为在类名后直接加括号的方法会定义一个没有对象名的临时对象,然后把这个临时对象赋给了stu2,这并不是通用的初始化方法(但是正确)。最好用通用的方法。
四、关于隐式类型转换,我查了一下别的书,的确,用=是隐式,用()是显式。说明如下:
class
Stu
{explict
Stu(int
a);
……};
加上显示声明关键字explict,只能进行显式声明:Stu
stu1(3);
如果不加,将可以这样隐式声明:Stu
s=3;
这个句子就相当于将3这个整型量转换成了Stu对象,在某些场合,这样的转换是十分危险的,加上explict后将杜绝这种可能性。
相关内容可以查阅“类型转换函数”。
我参考的书是《C++标准程序库》华中科技大学。
另外给点小建议,初学语言和熟悉环境(比方VC++)的过程中,细究语法是有必要的,但是学完继承,派生,虚函数,模板等概念以后,就要着重理解C++面向对象的思想,和用它解决实际问题的思路。
这就是他们的关系,正解
相似回答