对于c ++中的类,我们可以提供默认构造函数以及任何参数化构造函数。如果我们在每个参数化构造函数中使用构造函数初始化列表,那么就不像我们初始化一个成员不止一次?这个概念有效吗?(我以为我们只能初始化一次)。 同样通过这个逻辑,如果我们有一个常量数据成员或引用,并且如果我想用用户提供的值初始化常量,我该怎么办呢?我在c ++引子中找到了一个代码片段,看起来像
class constref
{
public:
constref(int ii):i(ii),ci(ii),ri(i)
{
}
private:
int i;
const int ci;
int &ri;
}
上面的代码不对。因为我们提供了一个带参数的构造函数,我们需要定义一个默认的构造函数。所以常量和引用被初始化两次,这是一个错误。我怎样才能使它工作? 感谢
但是,您能否告诉我们此代码中发生了什么?
#include<iostream>
#include<stdlib.h>
using namespace std;
class dummy
{
int a;
public:
dummy():a(0)
{
}
dummy(int i):a(i)
{
}
void output()
{
cout<<a<<endl;
}
};
int main()
{
dummy d;
d=dummy(4);
d=dummy(3);
d.output();
return 0;
}
答案 0 :(得分:3)
多个构造函数提供了多种初始化对象及其成员的方法。创建对象时使用一个构造函数,因此只有一个初始化。根据创建对象时给出的参数选择构造函数。
从示例中,constref c(3);
使用构造函数创建对象c
,将值3传递给构造函数。如果类还定义了默认构造函数,则会发生同样的事情。默认构造函数的存在不会影响c
的创建,因为默认构造函数不带参数,因此不能使用3作为参数调用。
答案 1 :(得分:1)
首先,没有必要提供默认构造函数但是如果你不提供它,就不能创建constref c1;
之类的对象,或者你甚至无法创建像constref c1[10]
这样的对象数组。你可以创建类constref的对象的唯一方法是向构造函数提供整数参数,即constref c1(10);
。
其次,常量和引用在代码中没有初始化两次。它们只被初始化一次,即interget“i:用”ii“初始化,constant int”ci“再次被”ii“初始化,类似于”ri“ “。
请注意,常量数据成员和引用必须是初始化列表,否则它将被编译器标记。
此外,数据成员初始化的顺序完全取决于它们在类中声明的方式(不是它们在初始化列表中出现的方式)。 考虑以下两种不同的情况: 的 Scenario1:强>
class constref
{
public:
constref(int ii):i(ii),ci(ii),ri(i)
{
}
private:
int i;
const int ci;
int &ri;
}
这里我将首先初始化,然后是ci和ri。
<强> scenario2:强>
class constref
{
public:
constref(int ii):i(ii),ci(ii),ri(i)
{
}
private:
const int ci;
int i;
int &ri;
}
这里首先初始化ci,然后是i,ri。
答案 2 :(得分:1)
没有冲突:初始化列表可以与空{ }
主体一起使用,也可以与带有语句的构造函数主体一起使用。
初始化列表只会将成员初始化为构造函数开头的特定值。
即使构造函数有一个初始化列表,你仍然可以在构造函数体中自由地做其他工作。
此:
Point(int i = 0, int j = 0):x(i), y(j) {}
等同于:
Point(int i = 0, int j = 0) {
x = i;
y = j;
}
如果将不同数量的变量传递给构造函数来初始化类,则只有不同的构造方法。任何带参数的构造函数都可以使用初始化列表。
<小时/> 默认构造函数是一个不带任何参数的构造函数。
您只需要在其中定义默认构造函数 需要在没有任何参数的情况下实例化该类的对象。
参考文献:
http://www.geeksforgeeks.org/when-do-we-use-initializer-list-in-c/