类对象作成员时初始化的一个有关问题
类对象作成员时初始化的一个问题
class X{
const int i;
int j;
int &b;
public:
X():i(0),j(0),b(j)
{
cout < < "X的带1个参数的构造函数\n " ;
}
X(int a):i(a),b(j)
{
j = 0;
cout < < "X的带1个参数的构造函数\n " ;
}
};
class Y{
int i;
X x;
public:
Y():i(0) //,x(10) 不在这里写了
{
x=10;//若在这里初始化x,在X类中无常成员和引用成员时是可以编译通过的时会先调用一个x的缺省构造,再调用带1参数的。为何有常成员或引用成员时就不行了呢?X的缺省构造的初始化列表中已经对他们初始化了呀
cout < < "Y的缺省构造函数\n " ;
}
};
------解决方案--------------------
第一:你的代码,X没有默认构造函数。在有其它任何自定义构造函数时,编译器是不会提供默认构造函数的。
第二:你的代码,X也没有赋值运算符。有常成员或引用成员时,编译器是不会提供赋值运算符的。
请有空务必认真学《Effective C++》
------解决方案--------------------
呃,眼太花了,你代码没问题1。
------解决方案--------------------
这里有一个基础知识点,就是在创建对象的时候, 应该调用构造函数,但是这时要注意! 在未进入
构造函数的大括号(函数体)里之前,对象的子对象已经创建(这里是x),在大括号(函数体)里面再给x "赋值 "(注意不是初始化哦!),但是很遗憾 , 你没有定义 operator = (int), 没有匹配的赋值操作符函数,所以出错,
因此错误不是没有给常量和引用赋值,而是调用了一个没有定义的函数.
------解决方案--------------------
effective c++ 2e item 45
More Effective C++ item 5
------解决方案--------------------
const 只能使用成员初始化列表
------解决方案--------------------
4种情况,需要在初始化列表里初始化。
1,const
2,reference
3,继承自某基类,该类有constructor
4,包含某类的对象,该类有constructor
------解决方案--------------------
参考《Inside c++ object model》
------解决方案--------------------
// 如果不写 operator = 系统会默认生成一个,但只是简单的位拷贝,
// 普通的变量可以位拷贝, 但是常变量不可以位拷贝,所以出错,
// 因此需要自己定义operator = 就可以解决问题了,虽然这样做太不厚道。
// 看下面修改后的程序
#include <iostream>
using namespace std;
class X{
const int i;
int j;
int &b;
public:
X():i(0),j(0),b(j)
{
cout < < "X的带0个参数的构造函数\n " ;
}
const X & operator = (const X &x) // !!! 只是为了说明问题,千万不要这样写,(《C++必知必会》条款11).
{
if (this == &x)
return *this;
memcpy((void*)&i, (void*)&x.i, sizeof(int)); // 不道德
j = x.j;
memcpy((void*)&b, (void*)&x.b, sizeof(int)); // 不道德
return *this;
}
X(int a):i(a),b(j)
{
j = 0;
cout < < "X的带1个参数的构造函数\n " ;
}
};
class Y{
int i;
X x;
public:
Y():i(0) //,x(10) 不在这里写了
{
x=10;//若在这里初始化x,在X类中无常成员和引用成员时是可以编译通过的时会先调用一个x的缺省构造,再调用带1参数的。为何有常成员或引用成员时就不行了呢?X的缺省构造的初始化列表中已经对他们初始化了呀
cout < < "Y的缺省构造函数\n " ;
}
};
int main(void)
{
Y y;
return 0;
};
------解决方案--------------------
你没搞错吧。
这不是当前贴的连接嘛?
死循环?
class X{
const int i;
int j;
int &b;
public:
X():i(0),j(0),b(j)
{
cout < < "X的带1个参数的构造函数\n " ;
}
X(int a):i(a),b(j)
{
j = 0;
cout < < "X的带1个参数的构造函数\n " ;
}
};
class Y{
int i;
X x;
public:
Y():i(0) //,x(10) 不在这里写了
{
x=10;//若在这里初始化x,在X类中无常成员和引用成员时是可以编译通过的时会先调用一个x的缺省构造,再调用带1参数的。为何有常成员或引用成员时就不行了呢?X的缺省构造的初始化列表中已经对他们初始化了呀
cout < < "Y的缺省构造函数\n " ;
}
};
------解决方案--------------------
第一:你的代码,X没有默认构造函数。在有其它任何自定义构造函数时,编译器是不会提供默认构造函数的。
第二:你的代码,X也没有赋值运算符。有常成员或引用成员时,编译器是不会提供赋值运算符的。
请有空务必认真学《Effective C++》
------解决方案--------------------
呃,眼太花了,你代码没问题1。
------解决方案--------------------
这里有一个基础知识点,就是在创建对象的时候, 应该调用构造函数,但是这时要注意! 在未进入
构造函数的大括号(函数体)里之前,对象的子对象已经创建(这里是x),在大括号(函数体)里面再给x "赋值 "(注意不是初始化哦!),但是很遗憾 , 你没有定义 operator = (int), 没有匹配的赋值操作符函数,所以出错,
因此错误不是没有给常量和引用赋值,而是调用了一个没有定义的函数.
------解决方案--------------------
effective c++ 2e item 45
More Effective C++ item 5
------解决方案--------------------
const 只能使用成员初始化列表
------解决方案--------------------
4种情况,需要在初始化列表里初始化。
1,const
2,reference
3,继承自某基类,该类有constructor
4,包含某类的对象,该类有constructor
------解决方案--------------------
参考《Inside c++ object model》
------解决方案--------------------
// 如果不写 operator = 系统会默认生成一个,但只是简单的位拷贝,
// 普通的变量可以位拷贝, 但是常变量不可以位拷贝,所以出错,
// 因此需要自己定义operator = 就可以解决问题了,虽然这样做太不厚道。
// 看下面修改后的程序
#include <iostream>
using namespace std;
class X{
const int i;
int j;
int &b;
public:
X():i(0),j(0),b(j)
{
cout < < "X的带0个参数的构造函数\n " ;
}
const X & operator = (const X &x) // !!! 只是为了说明问题,千万不要这样写,(《C++必知必会》条款11).
{
if (this == &x)
return *this;
memcpy((void*)&i, (void*)&x.i, sizeof(int)); // 不道德
j = x.j;
memcpy((void*)&b, (void*)&x.b, sizeof(int)); // 不道德
return *this;
}
X(int a):i(a),b(j)
{
j = 0;
cout < < "X的带1个参数的构造函数\n " ;
}
};
class Y{
int i;
X x;
public:
Y():i(0) //,x(10) 不在这里写了
{
x=10;//若在这里初始化x,在X类中无常成员和引用成员时是可以编译通过的时会先调用一个x的缺省构造,再调用带1参数的。为何有常成员或引用成员时就不行了呢?X的缺省构造的初始化列表中已经对他们初始化了呀
cout < < "Y的缺省构造函数\n " ;
}
};
int main(void)
{
Y y;
return 0;
};
------解决方案--------------------
你没搞错吧。
这不是当前贴的连接嘛?
死循环?