C++中设置类函数成员的默认值和构造函数的初始值有什么区别

如题所述

一般进行成员变量初始化用两种方法

第一种是通过在构造函数内赋值
class Point
{
public:
Point(){ _x = 0; _y = 0;};
Point( int x, int y ){ _x = 0; _y = 0; }
private:
int _x, _y;
};

第二种是使用初始化列表
class Point
{
public:
Point():_x(0),_y(0){};
Point( int x, int y ):_x(x),_y(y){}
private:
int _x, _y;
};

这两种用法是有区别的

一、在有些情况下,必须使用初始化列表。特别是const和引用数据成员被初始化时。

class Point
{
// 这个类的定义就要求使用初始化成员列表,因为const成员只能被初始化,不能被赋值
public:
Point():_x(0),_y(0){};
Point( int x, int y ):_x(x),_y(y){}
//Point(){ _x = 0; _y = 0;}
//Point( int x, int y ){ _x = 0; _y = 0; }
private:
const int _x, _y;
};

二、是从效率方面来说的,对于内置类型或复合类型,差异不会太大,但对于非内置数据类型,差异还是很明显的

如再给Point类添加一个新的string类型的成员变量

class Point
{
const int _x, _y;
string _name;
};

构造函数内赋值进行初始化

Point( int x, int y, string name ){ _x = 0; _y = 0; _name = name; }

_name = name 这个表达式会调用string类的缺省构造函数一次,再调用Operator=函数进行赋值一次。所以需调用两次函数:一次构造,一次赋值

用初始化列表进行初始化

Point( int x, int y, string name ):_x(x),_y(y), _name(name){}

_name会通过拷贝构造函数仅以一个函数调用的代码完成初始化

即使是一个很简单的string类型,不必要的函数调用也会造成很高的代价。随着类越来越大,越来越复杂,它们的构造函数也越来越大而复杂,那么对象创建的代价也越来越高,所以一般情况下使用初始化列表进行初始化,不但可以满足const和引用成员的初始化要求,还可以避免低效的初始化数据成员。
温馨提示:答案为网友推荐,仅供参考
第1个回答  推荐于2017-09-01
函数成员的默认值指的是默认参数值吗?这个和构造函数没什么关系
构造函数里面如果对成员函数进行调用,可以给成员函数的参数赋值,如果不赋值,那成员函数就用的默认参数值。

如果构造函数不调用成员函数,那么成员函数的默认参数和构造函数一点关系都没有。追问

我想你理解错我的意思了,我想问的是如果我要设置一个初始值,用构造函数来初始化和单独写一个成员函数来赋值,两者起到的效果是不是一样的?

追答

基本一样
严格说,生成同时赋值才叫初始化,所以构造函数里的赋值才叫初始化,成员函数里的叫赋值
你可以在构造函数里面调用成员函数来初始化,这是可以的

本回答被提问者和网友采纳
相似回答