#include <iostream>
using namespace std;
class Point3D
{
public:
//virtual ~Point3D();
public:
static Point3D origin;
float x,y,z;
};
int main()
{
Point3D temp;
cout<<temp.z<<endl; //这句在运行时会异常
cout<<&Point3D::z<<endl; // &Point3D::z 返回的是offset ,void* ,那么 cout<< void* 输出的也应该是地址啊,为什么全是1?
cout<<&Point3D::y<<endl;
cout<<&Point3D::x<<endl;
cout<<endl;
printf("&Point3D::z = %p\n",&Point3D::z);
printf("&Point3D::y = %p\n",&Point3D::y);
printf("&Point3D::x = %p\n",&Point3D::x);
}
出现异常的朋友们千万别说是没初始化,即使没初始化也要有默认值。而且只要加上默认构造函数就不会有异常了,为什么?
37 个解决方案
#1
没有构造函数,temp就是没定义,没分配内存,当然会出异常
那你可能就会问编译器不是会提供默认的构造函数吗?
下面的是在网上搜到的,没做验证
C++中一个类无任何构造函数,编译器在什么情况下才提供默认构造函数?
在C++中,如果一个类中没有定义任何的构造函数,那么编译器只有在以下三种情况,才会提供默认的构造函数:
1.如果类有虚成员函数或者虚拟继承父类(即有虚拟基类)时;
2.如果类的基类有构造函数(可以是用户定义的构造函数,或编译器提供的默认构造函数);
3.在类中的所有非静态的对象数据成员,它们所属的类中有构造函数(可以是用户定义的构造函数,或编译器提供的默认构造函数)。
那你可能就会问编译器不是会提供默认的构造函数吗?
下面的是在网上搜到的,没做验证
C++中一个类无任何构造函数,编译器在什么情况下才提供默认构造函数?
在C++中,如果一个类中没有定义任何的构造函数,那么编译器只有在以下三种情况,才会提供默认的构造函数:
1.如果类有虚成员函数或者虚拟继承父类(即有虚拟基类)时;
2.如果类的基类有构造函数(可以是用户定义的构造函数,或编译器提供的默认构造函数);
3.在类中的所有非静态的对象数据成员,它们所属的类中有构造函数(可以是用户定义的构造函数,或编译器提供的默认构造函数)。
#2
我这里没有异常,不知道你为什么要取一个类的共有成员的地址,这样可行吗?
#3
为什么不生成默认构造函数呢?VS2005
#4
一个类定义之后 如果不实例出对象或是其他方式为其内部成员分配内存 则他是不会开辟空间的 静态除外不过静态要事先做初始化
另外加上构造函数 为什么会有变化 原因很简单 他为代码做了必要的初始化工作 分配了空间给类成员
另外加上构造函数 为什么会有变化 原因很简单 他为代码做了必要的初始化工作 分配了空间给类成员
#5
我这没任何异常
#6
他为什么不生成默认构造函数呢?
#7
class Point3D
{
public:
//virtual ~Point3D();
public:
static Point3D origin;
float x,y,z;
};
编译器不会为应该由设计者自己提供初值的类成员变量进行初始化,如果设计者没有提供构造函数,如1楼所说的情况下,编译器会提供一个默认构造函数进行一些初始化操作,否则默认构造函数是无意义的;
在这里出现异常有可能是Z没有明确初始化
cout<<&Point3D::z<<endl; 类成员变量求地址只是求变量在对象内存布局中的偏移,
如果要求地址,必须用对象的成员变量
{
public:
//virtual ~Point3D();
public:
static Point3D origin;
float x,y,z;
};
编译器不会为应该由设计者自己提供初值的类成员变量进行初始化,如果设计者没有提供构造函数,如1楼所说的情况下,编译器会提供一个默认构造函数进行一些初始化操作,否则默认构造函数是无意义的;
在这里出现异常有可能是Z没有明确初始化
cout<<&Point3D::z<<endl; 类成员变量求地址只是求变量在对象内存布局中的偏移,
如果要求地址,必须用对象的成员变量
#8
讨论来讨论去,求这个有意义吗? 不知道哪儿有说这个操作是有意义的...
#9
cout<<temp.z<<endl; //这句在运行时会异常
没有初始化z变量!!
没有初始化z变量!!
#10
c++的《运算符好像没有重载这种输出吧!!!
#11
vc2005是很强暴的编译器,在debug状态下自动启用“变量没有初始化”的检查并报错。
根据C++标准,在楼主所说场合是不会自动生成默认构造函数的。
认真去重看基础教材C++ Primer吧。
根据C++标准,在楼主所说场合是不会自动生成默认构造函数的。
认真去重看基础教材C++ Primer吧。
#12
明白了没构造函数,但下面的还不明白:
cout<<&Point3D::z<<endl; // &Point3D::z 返回的是offset ,void* ,那么 cout<< void* 输出的也应该是地址啊,为什么全是1?
cout<<&Point3D::z<<endl; // &Point3D::z 返回的是offset ,void* ,那么 cout<< void* 输出的也应该是地址啊,为什么全是1?
#13
&Point3D::z 返回的是offset ,void*
哪本书告诉你的?扔了那破书。
#14
我也觉得那书说的有问题,那返回的是什么?
#15
返回的就是“指向成员的指针”,找本C++ Primer好好补课去。
#16
这指针有什么用?能比较大小吗?能装换成void* 吗?
C++ Primer 里没有这些内容吧,倒是其他C++ 大师书籍可能有。
#17
C++ Primer上说啥了?
#18
C++ Primer 里就是些 C++ 基本语法
#19
一楼的描述是对的,我已验证过
#20
那就去看C++标准。看过了C++标准,你对C++ Primer的认识就会完全不同了。
#21
老大,你就告诉我 &Point3D::z 返回的是什么吧。。。
#22
重复答案有什么意义?
#23
要你去C++ Primer补课,是让你自己找出“指向成员的指针”是C++新增的一种基本数据类型。
它其它什么都不是,它就是它自己。
它能做的(符合C++标准规定的)操作C++ Primer都讲了。
它其它什么都不是,它就是它自己。
它能做的(符合C++标准规定的)操作C++ Primer都讲了。
#24
那这个指针能不能转换?或比较大小?
#25
你这个 列子 是 不是 Inside C++ object modal 上的 ?
#26
C++ Primer上如果讲了可以那就可以,如果没讲可以那就不可以。
自己认真到书上找答案。
#27
没有发现任何异常,编译运行都成功
#28
可能编译器不同吧,&Point3D::z 咋比较大小呢?
#29
加上 构造函数
还有成员变量要初始化
还有成员变量要初始化
#30
Run-Time Check Failure #3 - The variable 'temp' is being used without being initialized.
-vs2008
没初始化是正解。
至于
&Point3D::z 返回的是offset 这话确实没有错
所以printf返回是正确的
但是<<没有对此进行重载,默认的是只是返回bool
基本上,等价于下面的语句
所以为1
cout << "Point3d::x = " << (bool) &Point3d::x << endl;
为了正确的输出
可以尝试下面的代码
float Point3D::*const pm = &Point3D::x;
cout << "Point3d::x = " << (const void *&) pm << endl;
-vs2008
没初始化是正解。
至于
&Point3D::z 返回的是offset 这话确实没有错
所以printf返回是正确的
但是<<没有对此进行重载,默认的是只是返回bool
基本上,等价于下面的语句
所以为1
cout << "Point3d::x = " << (bool) &Point3d::x << endl;
为了正确的输出
可以尝试下面的代码
float Point3D::*const pm = &Point3D::x;
cout << "Point3d::x = " << (const void *&) pm << endl;
#31
当然重载<<也是可以的。。。加上就可以了
template<class T, typename M>
ostream & operator <<(ostream &os, M T::*pm)
{
os << (const void *&) pm;
return os;
}
template<class T, typename M>
ostream & operator <<(ostream &os, M T::*pm)
{
os << (const void *&) pm;
return os;
}
#32
====================================
(const void *&) 能转吗?
&Point3d::x 我就没法转成任何类型
#33
学习了
#34
生成了默认构造函数的,不过对于float x,y,z;没帮你"默认构造",这不是VS2005的义务.
建议记住:
在对象构造函数里,将所有成员初始化, 你的责任!
在使用前将数组初始化, 你的责任!
在适当的时机将字串无效部分置零, 你可以活得久些!
对于cout<<&Point3D::z<<endl; // &Point3D::z 返回的是offset ,void* ,那么 cout<< void* 输出的也应该是地址啊,为什么全是1?
实在费解为什么会这么写:
对于 &Point3D::z 编译器给你解释为 (float Point3D::*) 看清楚了吧(不是 float* Point3D:: .... ), 是成员的偏移量, float 只起了个sizetype作用;
如果你用:
printf("%d,%d,%d",&Point3D::x,&Point3D::y,&Point3D::z);
输出为:
0,4,8 // 明白了吧.
如果你用cout的话,实际cout 把 (&Point3D::x) 当成bool量, 谁叫你搞这么奇异的东西....
operator<<(_Bool _Val)
所以输出为 "1" 了, 为什么 &Point3D::x printf输出0,count输出1呢,哈哈,注意下_Bool吧,自己研究下去...(俺知道,就不说)叫你写这东西
#35
是 float &Point3d::* x,,,,天书一般的东西,怎么理解都行,转就别想了
#36
哪里有说明是当bool ?
#37
这个不用说明,你跟踪一下就清楚了,或者看调用堆栈, 的确被当作 bool处理了,值全为 true
#1
没有构造函数,temp就是没定义,没分配内存,当然会出异常
那你可能就会问编译器不是会提供默认的构造函数吗?
下面的是在网上搜到的,没做验证
C++中一个类无任何构造函数,编译器在什么情况下才提供默认构造函数?
在C++中,如果一个类中没有定义任何的构造函数,那么编译器只有在以下三种情况,才会提供默认的构造函数:
1.如果类有虚成员函数或者虚拟继承父类(即有虚拟基类)时;
2.如果类的基类有构造函数(可以是用户定义的构造函数,或编译器提供的默认构造函数);
3.在类中的所有非静态的对象数据成员,它们所属的类中有构造函数(可以是用户定义的构造函数,或编译器提供的默认构造函数)。
那你可能就会问编译器不是会提供默认的构造函数吗?
下面的是在网上搜到的,没做验证
C++中一个类无任何构造函数,编译器在什么情况下才提供默认构造函数?
在C++中,如果一个类中没有定义任何的构造函数,那么编译器只有在以下三种情况,才会提供默认的构造函数:
1.如果类有虚成员函数或者虚拟继承父类(即有虚拟基类)时;
2.如果类的基类有构造函数(可以是用户定义的构造函数,或编译器提供的默认构造函数);
3.在类中的所有非静态的对象数据成员,它们所属的类中有构造函数(可以是用户定义的构造函数,或编译器提供的默认构造函数)。
#2
我这里没有异常,不知道你为什么要取一个类的共有成员的地址,这样可行吗?
#3
为什么不生成默认构造函数呢?VS2005
#4
一个类定义之后 如果不实例出对象或是其他方式为其内部成员分配内存 则他是不会开辟空间的 静态除外不过静态要事先做初始化
另外加上构造函数 为什么会有变化 原因很简单 他为代码做了必要的初始化工作 分配了空间给类成员
另外加上构造函数 为什么会有变化 原因很简单 他为代码做了必要的初始化工作 分配了空间给类成员
#5
我这没任何异常
#6
他为什么不生成默认构造函数呢?
#7
class Point3D
{
public:
//virtual ~Point3D();
public:
static Point3D origin;
float x,y,z;
};
编译器不会为应该由设计者自己提供初值的类成员变量进行初始化,如果设计者没有提供构造函数,如1楼所说的情况下,编译器会提供一个默认构造函数进行一些初始化操作,否则默认构造函数是无意义的;
在这里出现异常有可能是Z没有明确初始化
cout<<&Point3D::z<<endl; 类成员变量求地址只是求变量在对象内存布局中的偏移,
如果要求地址,必须用对象的成员变量
{
public:
//virtual ~Point3D();
public:
static Point3D origin;
float x,y,z;
};
编译器不会为应该由设计者自己提供初值的类成员变量进行初始化,如果设计者没有提供构造函数,如1楼所说的情况下,编译器会提供一个默认构造函数进行一些初始化操作,否则默认构造函数是无意义的;
在这里出现异常有可能是Z没有明确初始化
cout<<&Point3D::z<<endl; 类成员变量求地址只是求变量在对象内存布局中的偏移,
如果要求地址,必须用对象的成员变量
#8
讨论来讨论去,求这个有意义吗? 不知道哪儿有说这个操作是有意义的...
#9
cout<<temp.z<<endl; //这句在运行时会异常
没有初始化z变量!!
没有初始化z变量!!
#10
c++的《运算符好像没有重载这种输出吧!!!
#11
vc2005是很强暴的编译器,在debug状态下自动启用“变量没有初始化”的检查并报错。
根据C++标准,在楼主所说场合是不会自动生成默认构造函数的。
认真去重看基础教材C++ Primer吧。
根据C++标准,在楼主所说场合是不会自动生成默认构造函数的。
认真去重看基础教材C++ Primer吧。
#12
明白了没构造函数,但下面的还不明白:
cout<<&Point3D::z<<endl; // &Point3D::z 返回的是offset ,void* ,那么 cout<< void* 输出的也应该是地址啊,为什么全是1?
cout<<&Point3D::z<<endl; // &Point3D::z 返回的是offset ,void* ,那么 cout<< void* 输出的也应该是地址啊,为什么全是1?
#13
&Point3D::z 返回的是offset ,void*
哪本书告诉你的?扔了那破书。
#14
我也觉得那书说的有问题,那返回的是什么?
#15
返回的就是“指向成员的指针”,找本C++ Primer好好补课去。
#16
这指针有什么用?能比较大小吗?能装换成void* 吗?
C++ Primer 里没有这些内容吧,倒是其他C++ 大师书籍可能有。
#17
C++ Primer上说啥了?
#18
C++ Primer 里就是些 C++ 基本语法
#19
一楼的描述是对的,我已验证过
#20
那就去看C++标准。看过了C++标准,你对C++ Primer的认识就会完全不同了。
#21
老大,你就告诉我 &Point3D::z 返回的是什么吧。。。
#22
重复答案有什么意义?
#23
要你去C++ Primer补课,是让你自己找出“指向成员的指针”是C++新增的一种基本数据类型。
它其它什么都不是,它就是它自己。
它能做的(符合C++标准规定的)操作C++ Primer都讲了。
它其它什么都不是,它就是它自己。
它能做的(符合C++标准规定的)操作C++ Primer都讲了。
#24
那这个指针能不能转换?或比较大小?
#25
你这个 列子 是 不是 Inside C++ object modal 上的 ?
#26
C++ Primer上如果讲了可以那就可以,如果没讲可以那就不可以。
自己认真到书上找答案。
#27
没有发现任何异常,编译运行都成功
#28
可能编译器不同吧,&Point3D::z 咋比较大小呢?
#29
加上 构造函数
还有成员变量要初始化
还有成员变量要初始化
#30
Run-Time Check Failure #3 - The variable 'temp' is being used without being initialized.
-vs2008
没初始化是正解。
至于
&Point3D::z 返回的是offset 这话确实没有错
所以printf返回是正确的
但是<<没有对此进行重载,默认的是只是返回bool
基本上,等价于下面的语句
所以为1
cout << "Point3d::x = " << (bool) &Point3d::x << endl;
为了正确的输出
可以尝试下面的代码
float Point3D::*const pm = &Point3D::x;
cout << "Point3d::x = " << (const void *&) pm << endl;
-vs2008
没初始化是正解。
至于
&Point3D::z 返回的是offset 这话确实没有错
所以printf返回是正确的
但是<<没有对此进行重载,默认的是只是返回bool
基本上,等价于下面的语句
所以为1
cout << "Point3d::x = " << (bool) &Point3d::x << endl;
为了正确的输出
可以尝试下面的代码
float Point3D::*const pm = &Point3D::x;
cout << "Point3d::x = " << (const void *&) pm << endl;
#31
当然重载<<也是可以的。。。加上就可以了
template<class T, typename M>
ostream & operator <<(ostream &os, M T::*pm)
{
os << (const void *&) pm;
return os;
}
template<class T, typename M>
ostream & operator <<(ostream &os, M T::*pm)
{
os << (const void *&) pm;
return os;
}
#32
====================================
(const void *&) 能转吗?
&Point3d::x 我就没法转成任何类型
#33
学习了
#34
生成了默认构造函数的,不过对于float x,y,z;没帮你"默认构造",这不是VS2005的义务.
建议记住:
在对象构造函数里,将所有成员初始化, 你的责任!
在使用前将数组初始化, 你的责任!
在适当的时机将字串无效部分置零, 你可以活得久些!
对于cout<<&Point3D::z<<endl; // &Point3D::z 返回的是offset ,void* ,那么 cout<< void* 输出的也应该是地址啊,为什么全是1?
实在费解为什么会这么写:
对于 &Point3D::z 编译器给你解释为 (float Point3D::*) 看清楚了吧(不是 float* Point3D:: .... ), 是成员的偏移量, float 只起了个sizetype作用;
如果你用:
printf("%d,%d,%d",&Point3D::x,&Point3D::y,&Point3D::z);
输出为:
0,4,8 // 明白了吧.
如果你用cout的话,实际cout 把 (&Point3D::x) 当成bool量, 谁叫你搞这么奇异的东西....
operator<<(_Bool _Val)
所以输出为 "1" 了, 为什么 &Point3D::x printf输出0,count输出1呢,哈哈,注意下_Bool吧,自己研究下去...(俺知道,就不说)叫你写这东西
#35
是 float &Point3d::* x,,,,天书一般的东西,怎么理解都行,转就别想了
#36
哪里有说明是当bool ?
#37
这个不用说明,你跟踪一下就清楚了,或者看调用堆栈, 的确被当作 bool处理了,值全为 true