请问初始化成员表达式和在函数体内赋值表达式有什么区别?
比方说我定义了一个类:
class point
{
public:
point();
point(int a,intb);
private:
int m, n;
};
在实现类成员函数时,
(1). point::point(int a,intb)
{
m=a;
n=b;
}
(2). point::point(int a, int b):m(a),n(b)
{
}
(1),(2)有什么区别?(不 是指形式,而是结果的区别)
还有:
初始化成员表达式有没有什么特殊用途(不同于“=”的)?
初始化成员列表一般情况下比赋值效率高,在你这个程序里没表现出来,但如果你用其他类对象来复制构造一个类对象时,如果在复制构造函数体内调用operator = ,那么该对象在进入复制构造函数的大括号之前就已经调用了一次它自己的默认构造函数,然后才又在复制构造函数体内调用其operator = ;如果该对象没有默认的构造函数则你不可以在函数体内使用operator = 来模拟初始化,而必须在初始化成员列表中对其进行初始化。
所以如果不在初始化成员列表中初始化类对象,则初始化一个类对象就需要调用一次构造和一次operator = ,而在初始化成员列表中初始化则只调用一次复制构造;
对于内置类型来说使用operator = 和使用初始化成员列表没有大的区别,但为了保持一致性,最好也使用初始化成员列表,而且在某些情况下非使用列表,比如类中有引用或者const量,则只能在初始化成员列表中对其进行初始化。
另一篇关于初始化列表的文章:
C++ 初始化类的成员,不但可以用构造函数(constructor)完成,而且可以用初始化类成员列表来完成。MFC大量用到此方法。例如有些初学者可能不大理解如下代码:
class A
{
public:
int member_var; //成员变量
A(); //构造函数
}
A::A():member_var(0)
{
}
他们觉得这个构造函数的定义应该只能这样写:
A::A()
{
member_var=1;
}
其实两种方法都可。但是有些情况下,只能用第一种,而且通常情况下用第一种也会效率高些。
其实,第一种方法是真正的初始化(initialization ),而在构造函数内实现的“=”操作其实是赋值(assign)。这两种方法的一切区别从这儿开始。区别大概如下:
我们知道普通变量编译器都会默认的替你初始化。他们既能初始化,也能被赋值的,而常量(const)按照其意思只能被初始化,不能赋值。否则与变量就无区别了。所以常量成员(const member)只能用成员初始化列表来完成他们的“初始化”,而不能在构造函数内为他们“赋值”。
我们知道类的对象的初始化其实就是调用他的构造函数完成,如果没有写构造函数,编译器会为你默认生成一个。如果你自定义了带参数的构造函数,那么编译器将不生成默认构造函数。这样这个类的对象的初始化必须有参数。如果这样的类的对象来做另外某个类的成员,那么为了初始化这个成员,你必须为这个类的对象的构造函数传递一个参数。同样,如果你在包含它的这个类的构造函数里用“=”,其实是为这个对象“赋值”而非“初始化”它。所以一个类里的所有构造函数都是有参数的,那么这样的类如果做为别的类的成员变量,你必须显式的初始化它,你也是只能通过成员初始化列表来完成初始化。 例如:
class B
{
......
}
class A
{
public:
B member_b;
A();
}
A::A():B(...) //你必须显式初始化它,因为他的所有构造函数
//都是有参数的,之后才能被赋值。
{
B=...; //因为如上所写,已经初始化了,才能被赋值,否则错误。
}
——————————————————————————————————————
初始化顺序:
class test
{
const int a;
std:string str;
object o;
test():str(“df”),o(null) ,a(0)
{
}
};
黄色的既是初始化列表,他们会在构造函数正式调用前被调用 ,且他们的初始化顺序并不是根据 初始化列表中出现的顺序,而是他们声明的顺序来初始化。如上:
初始化顺序是: a, str, o;
一般用于初始化 常量类型,静态类型的数据,或者不能独立存在的数据