C++访问静态成员的问题

royuusyou 2007-11-24 08:22:48
我是C++的新手,今天在书上看到了这样一段话:
如果使用成员选择运算符“.”和“->”来调用类的静态成员函数和静态数据成员时候,表达式中运算符“.”和“->”前面的表达式不会被求值,如果在这部分进行了函数调用,则这些函数永远也不会真正被调用。
例如:
假设1.变量i是类MyClass的静态成员变量
假设2.GetMyClass()的返回值是一个类型为MyClass的实例对象
则:GetMyClass().i = 1;
上面的表达式中,编译器不对GetMyClass()进行求值,实际上该函数永远不会被调用,函数的代码也不会被执行。

上面是书上说的,但是我实际编码中却发现不是这样的情况,GetMyClass()函数还是会被调用。以下是我的代码:

#include<iostream>
using namespace std;

class MyClass
{
public:
static int i;
static void setI(int v);
static int getI();
};
int MyClass::i;
void MyClass::setI(int v)
{
i = v;
}
int MyClass::getI()
{
return i;
}

MyClass GetMyClass()
{
cout<<"GetMyClass"<<endl;
return MyClass();
}
int main()
{
MyClass myObject;
myObject.i = 321;
GetMyClass().i=111;
GetMyClass().setI(123);

cout<<"myObject.i="<<myObject.i<<endl
<<"GetMyClass().i="<<GetMyClass().getI()<<endl;
return 0;
}




输出结果是:
GetMyClass
GetMyClass
GetMyClass
GetMyClass
myObject.i=123
GetMyClass().i=123


但是有一个警告:

warning C4101: 'myObject' : unreferenced local variable


我的疑问还有:

输出结果说明“.”和“->”前面的会被引用,但是那条警告不是说明myObject对象没被引用吗?这两者互相矛盾,不知是哪里出了问题?

希望哪位大虾指点一二,谢谢!
...全文
259 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
懒得打字 2007-11-24
  • 打赏
  • 举报
回复
为什么我的输出是这个?
和lz的不同

GetMyClass
GetMyClass
GetMyClass
myObject.i=123
GetMyClass().i=123

期望高人指点
vc6.0编译


ps
warning C4101: 'myObject' : unreferenced local variable
是因为你没有用到myObject
而myObject.i是用到了类MyClass没有用到对象myObject
thecorr 2007-11-24
  • 打赏
  • 举报
回复
编译器 又是你的错。。。
懒得打字 2007-11-24
  • 打赏
  • 举报
回复
为什么我的输出是这个?
和lz的不同

GetMyClass
GetMyClass
GetMyClass
myObject.i=123
GetMyClass().i=123

期望高人指点
sinux_1983 2007-11-24
  • 打赏
  • 举报
回复
很不错的论题,期待高手来总结一下帖子。:-)
sinux_1983 2007-11-24
  • 打赏
  • 举报
回复
LZ的认真值得表扬,从现在的讨论看来编译器的做法确实有点双重标准,但是这也没办法啊,看书的时候是理想主义,一落实到代码就要变成现实主义了。 谁让我们不用二进制直接编程呢,那样就不用编译器了。
哈哈。
zhangyanli 2007-11-24
  • 打赏
  • 举报
回复
假设1.变量i是类MyClass的静态成员变量
假设2.GetMyClass()的返回值是一个类型为MyClass的实例对象
则:GetMyClass().i = 1;
上面的表达式中,编译器不对GetMyClass()进行求值,实际上该函数永远不会被调用,函数的代码也不会被执行。
-----------------------------------------------------
我发表一下我的看法无论如何程序流是肯定进入GetMyClass函数里了。而你的代码里还有别的部分代码,如输出什么的。
而你的书上说的,我觉得很大程度上是依赖于编译器的,或者说是编译期相关的。而从本质上讲这里是不应该进行函数调用的。warning C4101: 'myObject' : unreferenced local variable
而这句警告也恰恰证明了这点。只是函数的话可能有别的代码,所以编译器有的进行了优化,忽略了调用而有的则没有。
也许正如 “不接不舒服斯基”说的,你的书上说的太绝对了。世上没有绝对的事。
ckt 2007-11-24
  • 打赏
  • 举报
回复
你自己再看好好看一遍,你的代码和别人给你的回复

你觉得矛盾的是怎么理解的呢?.

这两条语句中对“myObject”的使用不起作用,跟下面两条语句
---------
static数据成员并不是属于对象,即使你通过对象引用,还是会被转换成形如MyClass::i

GetMyClass().i=111; 这里没警告并不意味这说是通过对象来调用的
只是这是一个临时对象,编译器就不会在出警告信息了。
royuusyou 2007-11-24
  • 打赏
  • 举报
回复
TO xiaoQ008:

类里面的静态怎么不初始化! i怎么不初始化!
===========

类里面的静态变量i只是一个声明
要初始化也是在类外面定义时候初始化呀
int MyClass::i=0;
royuusyou 2007-11-24
  • 打赏
  • 举报
回复
TO sinux_1983:


可能你误解我的意思了:
给出这条警告消息(warning C4101: 'myObject' : unreferenced local variable ),不是为了怎么解决这条警告,只是觉得从这条警告消息中可以看出:
myObject.i = 321;

cout<<"myObject.i="<<myObject.i<<endl
这两条语句中对“myObject”的使用不起作用,跟下面两条语句

GetMyClass().i=111;
GetMyClass().setI(123);

对“GetMyClass()”的使用却起作用相互矛盾。
xiaoQ008 2007-11-24
  • 打赏
  • 举报
回复
说实话
你这程序很不标准
类里面的静态怎么不初始化! i怎么不初始化!
ckt 2007-11-24
  • 打赏
  • 举报
回复
只能说你书上将的太绝对了

通过你的代码证明
深度探索C++对象模型里的说法(我引用的哪种说法)才是对的

sinux_1983 2007-11-24
  • 打赏
  • 举报
回复
>假设1.变量i是类MyClass的静态成员变量
>假设2.GetMyClass()的返回值是一个类型为MyClass的实例对象
>则:GetMyClass().i = 1;
>上面的表达式中,编译器不对GetMyClass()进行求值,实际上该函数永远不会被调用,函数的代码也不会被执行。
这个结论应该是依赖于编译器的。因为理论上说,进行类方法调用根本就不需要对象的,所以在这种情况下,编译器完全可以在此直接调用static函数,不需要对GetClass()进行求值的。

warning C4101: 'myObject' : unreferenced local variable
从这个警告来看在执行语句时 myObject.i = 321; 编译器并没有用对象,而是直接进行了类方法调用。
我在DEV-C++里编译了一下,没有警告。
一楼已经给出了答案,加一个构造函数就行了。


royuusyou 2007-11-24
  • 打赏
  • 举报
回复
TO ckt1120
是在<<Visual C++6.0编程指南>>(航空工业出版社 张海棠主编)的书上第42页说的。
royuusyou 2007-11-24
  • 打赏
  • 举报
回复
TO fogerasp :


在没加构造函数时候,main()函数里不是已经包含对myObject的使用了吗?
myObject.i = 321;


cout < <"myObject.i=" < <myObject.i < <endl

为什么还会出现那条警告消息呢?
我想应该是跟书上说的“myObject.i”表达式里“.”前面的部分(myObject)不会被求值,也不会被调用,所以才会出现说没被使用的警告。
但是我的输出结果中却有“GetMyClass”这样的内容,这内容是在调用“GetMyClass().i”的时候对“.”前面的“GetMyClass()”这个函数进行求值,调用了这个函数,所以说和前面说的有矛盾。
ckt 2007-11-24
  • 打赏
  • 举报
回复
输出结果说明“.”和“-> ”前面的会被引用,
但是那条警告不是说明myObject对象没被引用吗?这两者互相矛盾,不知是哪里出了问题?
------------

即使
GetMyClass().setI(123); 返回了一个临时对象,
通过.或->访问static数据成员或成员函数,也不是对象的引用,
直接访问属于的数据(static)
ckt 2007-11-24
  • 打赏
  • 举报
回复
如果使用成员选择运算符“.”和“-> ”来调用类的静态成员函数和静态数据成员时候,
表达式中运算符“.”和“-> ”前面的表达式不会被求值,如果在这部分进行了函数调用,则这些函数永远也不会真正被调用。
---------
那本书上讲的呢?

应该是 这种行为在C++ Standard里面没有规定,
有的编译器丢掉这样的函数调用(但不是是所有的都这样)
liumingrong 2007-11-24
  • 打赏
  • 举报
回复
GetMyClass().i=123 ;
不同的编译器对此实现可能不一样,有些编译器会忽略GetMyClass()函数调用,另一些则可能生产了临时对象
(c++对象模型一书有论述)
ryfdizuo 2007-11-24
  • 打赏
  • 举报
回复
其实lz你那个函数:
MyClass GetMyClass()
{
cout <<"GetMyClass" <<endl;
return MyClass();
}
之所以起作用是因为:返回的时候是MyClass();
编译器根本没有对GetMyClass()进行求值:就是说函数返回值的处理;
GetMyClass函数相当于没有执行;
MyClass().i = 100;
GetMyClass().i = 100;
二者效果一样,所以我猜想书中的本意是这样子的,只不过可能没有表达清楚;
tangshuiling 2007-11-24
  • 打赏
  • 举报
回复
楼主的前段描述,我实在没看懂。不过还是有点个人的看法:
1、静态成员变量i在预编译期就已经在内存中占有一席之地。因此,静态成员变量都要初始化。
2、静态成员变量与静态的成员函数都只存在一份,言外之意就是说,没有那个类对象独自拥有静态的成员,因此,静态成员函数没有this(用以表明这是我)指针。
3、楼主的代码中i变量用哪个类对象都可以去改变其值,但都是修改的同一个值。
Fogers 2007-11-24
  • 打赏
  • 举报
回复
加个构造函数就行了

MyClass(){};

warning C4101: 'myObject' : unreferenced local variable
这句是警告你 myObject 被声明 但未使用

64,668

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧