This topic has been archived. It cannot be replied.
-
工作学习 / 科技领域杂谈 / 简单技术问题。C++里面类的静态成员函数,有什么常见应用吗?好像可以用来作为线程函数和回调函数,可是,它又不能访问类的非静态成员,为什么非要把它放到类里?我能想到的应用是操作静态数据成员。可是非静态函数也可以操作静态数据成员啊。
-leonardmars(小马识途);
2013-7-12
(#8288234@0)
-
可以不通过Object直接调用那个函数。
-8749236(先头炮灰);
2013-7-12
{638}
(#8288327@0)
-
补充一个例子(虽然不是个好例子)
-8749236(先头炮灰);
2013-7-12
{715}
(#8288337@0)
-
静态成员变量我完全理解,就是静态成员函数不大理解。它干的活,普通成员函数或类外函数都能干。我没看到它存在的必要性,或者说优势吧。
-leonardmars(小马识途);
2013-7-13
(#8289004@0)
-
静态函数不需要对象。
-smallniuge(_);
2013-7-13
(#8289131@0)
-
这个好像有点道理。可是,如果确实不需要对象,普通的类外函数不是就可以搞定?不过那样就破坏了类的封装性,从这个角度看,倒是确实有必要。看来主要应用还是操作静态变量,与我想象符合。
-leonardmars(小马识途);
2013-7-13
(#8289275@0)
-
当你只希望那个类在整个程序里是独有的时候,很有用。然后再把constructor往private下一藏..=D
-8749236(先头炮灰);
2013-7-14
(#8289868@0)
-
谢谢回复,这些我都理解.我的疑惑是:这些事情普通外部函数都可以做到,为什么非要把静态函数放到类中?静态函数又不能操作类的普通成员?
-leonardmars(小马识途);
2013-7-12
(#8288611@0)
-
权限问题。
-8749236(先头炮灰);
2013-7-14
{633}
(#8289881@0)
-
最常见用法:用一个 class 放你 helper (static) methods, e.g.,: double d = Utilities.FahrenheitToCelsius(90); 另外 singleton 什么的... Is it what u were asking? 好处?一看 static 就知道是 stateless (除非访问一堆 static members)...
-xmlhttprequest(build5381);
2013-7-13
(#8289094@0)
-
第一个例子没太明白。singleton 确实是个好例子。我还没完整底学习过设计模式呐,得再看看书。谢谢。
-leonardmars(小马识途);
2013-7-13
(#8289290@0)
-
如果不太明白第一个例子,就先别急着看 design pattern。这么说吧,如果你写了个 method,IDE 发现你没有使用任何 instance members (and not even static members),IDE 会建议你将其 mark 成 static method,下次你一看到,就知道改变它影响的只是它自己(简化说法)。
-xmlhttprequest(build5381);
2013-7-13
(#8289312@0)
-
这回明白了。谢谢!还有一点疑惑:把这样的函数封装到类里面,是不是为了保证类的封装性?或者叫功能的完整性吧--等于是集成了一个通用功能到类的里面去。可是这样的功能与类分开有什么不好吗?比如STL里面,容器只保留基本功能,通用方法尽量设计成独立的。
-leonardmars(小马识途);
2013-7-13
(#8289335@0)
-
之前想回你的贴又忍住了,因为这个实在不是什么好东西。C++是multi-paradigm的语言,这是一个当时为吸引C程序员而不OO的又没有什么必要的设计。我感觉是C++设计的败笔之一。
-geekcode(吉克码工);
2013-7-13
(#8289399@0)
-
啊?败笔?不至于吧。C++兼容C,当然不能完全OO了。好像effective C++ 里面说过,C++其实是4种风格的语言。类的静态成员确实没有必要吗?至少静态数据成员还是很有必要的吧?谢谢
-leonardmars(小马识途);
2013-7-13
(#8289408@0)
-
这是我的想法,与你探讨。
-geekcode(吉克码工);
2013-7-14
{749}
(#8289753@0)
-
没有不好的pattern, 只有被误用/滥用的 pattern....
-xmlhttprequest(build5381);
2013-7-14
(#8289873@0)
-
只听说过C不兼容C++……还没听说过C++不兼容C……我找到的古老的C的代码统统都能编译并运行……我用的是MSVS2010...
-8749236(先头炮灰);
2013-7-14
(#8289882@0)
-
建议您先找本C++入门看看。
-geekcode(吉克码工);
2013-7-14
(#8289957@0)
-
这两天一直在想这个问题,抱歉现在才来回复。和大家的讨论对我非常有启发,下面是我的想法。标题以你文中的标号为准。
-leonardmars(小马识途);
2013-7-15
{564}
(#8291031@0)
-
简单回复一下。
-geekcode(吉克码工);
2013-7-16
{885}
(#8293226@0)
-
老兄,看来我的程度比你差得太远。请教:构造的时候传入,是传入共享对象的指针或引用吗?其实,本帖是我编程的时候遇到的问题。对高手来说,应该非常简单,等我把问题写出来,请不吝赐教。谢谢
-leonardmars(小马识途);
2013-7-16
(#8293424@0)
-
小马用汉语学习编程么?俺从你的帖子学到了两个汉语单词:类和静态。
-wincity(红卫兵);
2013-7-16
{42}
(#8293434@0)
-
是啊,我出来的晚,在国内就学过一点。英文又比较差,看英文书进度太慢,一着急就把中文书抄起来了。你是全英文学的编程吧?
-leonardmars(小马识途);
2013-7-16
(#8293536@0)
-
4的说法有点极端。自己工作的application范畴里没有用到不一定这个feature在所有的领域都没用。相反,很多领域里其实很依赖这些。比如说
-autumn_wind(al);
2013-7-16
{983}
(#8292131@0)
-
你举的例子就是一个典型的错误。你可以换一个角度考虑一下,如果没有静态变量,用什么方法去实现,然后哪一种更好。所谓的senior程序员都应该熟知这些方法,我就不重复了。只有没有alternative,才能算“rely on”吧。
-geekcode(吉克码工);
2013-7-16
{42}
(#8293192@0)
-
我明白你的意思。如果在内存很紧张,performance十分严格的条件下,分开成两个类是不可取的。
-autumn_wind(al);
2013-7-17
(#8293974@0)
-
咱举个最简单的例子。一个类的所有instance都需要命名,名字就起"class_a.0", "class_a.1", "class_a.2".....,命名的结尾是以0开始的序列号。不用static,不能依赖外部函数,但是一定要把这个序列号的功能封装进这个类(毕竟只有这个类用),你给我找个办法出来如果你能找到,我这里拜你为师了,哈哈~~
-autumn_wind(al);
2013-7-17
{38}
(#8294052@0)
-
大概我还保持着面向过程设计的思路。完全的面向对象,所有的方法都是封装到类里面的,是这样吗?
-leonardmars(小马识途);
2013-7-13
(#8289336@0)
-
简单说,是的。我上面说的,只是把一堆相关的静态 procedure 给 group 起来,你还是需要给它们一个 class。但 static methods 用法远不仅如此而已。
-xmlhttprequest(build5381);
2013-7-13
(#8289392@0)
-
越来越清晰了。至少我看到了它存在的必要性。其他的应用还得慢慢学。再次感谢。
-leonardmars(小马识途);
2013-7-13
(#8289401@0)
-
静态成员函数和静态变量一样,等于是建立了一个公用指针,等于OO之后留了一个非OO的后门。就象dotnet也留了一个使用指针的后门。
-getalife(生活啊生活);
2013-7-13
(#8289364@0)
-
这个没想到,容我再想想。谢谢
-leonardmars(小马识途);
2013-7-13
(#8289382@0)
-
学C++的,关注一下刚出来的11版,有巨大的改变,据C++之父说,C++11就像完全是一个新的语言
-binghongcha76(一只大猫);
2013-7-16
(#8292020@0)
-
能不能简单介绍一下?谢谢。全新的?完料,又得从新学。可怜我老版还没学全呐。
-leonardmars(小马识途);
2013-7-16
(#8292050@0)
-
是比较坑爹,看了一下,加入了函数式编程的语法,其他的就不懂了,对C++不熟,只不过江湖上传闻变化巨大,到现在也没有编译器100%支持,微软VS2013支持一部分,完全支持C++11的编译器至少要到2015年吧,所以现在不用担心
-binghongcha76(一只大猫);
2013-7-16
(#8292085@0)
-
A toy example:
-hhyang(?!);
2013-8-1
{7363}
(#8314876@0)
-
没想明白,首先create()一定要定义成静态吗?普通函数不可以吗?其次,这样设计岂不是把A和他的子类耦合到一起了?我水平太差,别笑话啊。
-leonardmars(小马识途);
2013-8-2
(#8316670@0)
-
B and C are subclasses of A, so they are coupled with A by definition.'create' is a 'factory' method to build an object of class A or its subclasses. A factory class is usually used to build objects of other classes, this is the fundamental idea of factory pattern.
Declaring function 'create' as non-static makes no sense if A has a pure virtual function. But, if A has a pure virtual function, my 'create' function has a bug, ha ha...
-hhyang(?!);
2013-8-2
{379}
(#8316690@0)
-
介个。父类和子类肯定是高度耦合的,不过,俺赶脚设计时也是尽量降低耦合比较好。像这个例子,A要知道自己有哪些子类,岂不是耦合得太厉害了?以后万一增加一个子类,还要修改A 的create 方法。
-leonardmars(小马识途);
2013-8-2
(#8316879@0)
-
ok. 也就是这个似A非A的函数知道A的子类而已,标准factory pattern 里整一堆factory class,个个知道A,B,C,耦合得岂不更厉害?呵呵。。。再说了,A,B,C本来就是耦合在一起的,如果这样做不是问题的话,用一个似A非A的函数去实例化这些类,并没有增添新的耦合。
如果创建一个对象,逻辑很复杂,俺这么个简单的函数就不好用了,所以俺说这是个toy example.
-hhyang(?!);
2013-8-2
{203}
(#8316900@0)
-
好吧。不过我仍然没看到静态成员函数的必要性。另外,这个例子还是不太好理解,一般设计的原则是只有最底层的类是可以实例化的,上层的尽量设计成纯虚类。如果A需要实例化,为什么不设计一个D,用它来代替A?这样工厂实例化的时候,是BCD,都是A的子类,这样的层次不是更清晰?也降低了耦合。
-leonardmars(小马识途);
2013-8-2
{78}
(#8316947@0)
-
也行。办法是多种多样的,看个人的取舍了。我不关心C++究竟应不应该保留这一feature. 不过,一个类的静态成员函数在这个类实例化之前就可以使用,这还是有点儿意思的。一个类的静态成员函数跟非静态成员函数是不一样的,我想在底层实现上,静态成员函数会跟全局函数放在一起,非静态成员函数会放在一个表里。
-hhyang(?!);
2013-8-2
{130}
(#8316966@0)
-
恩,我只是好奇,似乎没看到必要性。可能就像那位说的,在OO里面留个后门,以备万一。
-leonardmars(小马识途);
2013-8-2
(#8317052@0)
-
说点儿自己的理解,望科班儿的童鞋斧正:
-hhyang(?!);
2013-8-2
{556}
(#8317356@0)
-
不是科班出身,俺先喷你一下:OO不是那么简单滴,还有多态性聂。
-leonardmars(小马识途);
2013-8-2
(#8317592@0)
-
OO is a simple concept, but with tremendous consequences. :-)
-hhyang(?!);
2013-8-3
(#8318056@0)
-
和你谈讨一下。
-geekcode(吉克码工);
2013-8-2
{1192}
(#8317989@0)
-
咱接着扯这些个理论:
-hhyang(?!);
2013-8-3
{1866}
(#8318054@0)
-
I don't know what made the language designer (Bjarne Stroustrup?) choose static function of a class as a C++ feature, but I'm OK with this. I ever read a paper talking about using C in an OO way, that really opens my eyes.
-hhyang(?!);
2013-8-2
(#8316818@0)
-
This is not a good example of the static function. Bcoz
-autumn_wind(al);
2013-8-6
{1975}
(#8320039@0)
-
I don't quite understand your question, here is my guess:
-hhyang(?!);
2013-8-6
{3047}
(#8320141@0)
-
I can see the improvements. Yup, keep going along this path...
-autumn_wind(al);
2013-8-6
(#8320263@0)
-
I am not sure about the goal to achieve, I'll stop here for now.
-hhyang(?!);
2013-8-6
(#8320301@0)
-
受教了,谢谢。就是说主要的应用还是作为线程函数和回调函数喽。静态成员函数访问非静态成员?是不是用一个静态指针指向第一个对象,然后用一个链表把所有的对象串起来。通过这个指向第一个对象的静态指针,就可以遍历所有对象。
-leonardmars(小马识途);
2013-8-6
(#8320151@0)
-
别客气,都基础知识。不过要批评一下哈,你给的这个是很缺乏编程经验的方案,答案其实很简单。很多OS的编程虽然是用C,但是已经考虑到这个问题了。所以,请查一下一般接口的参数,比如注册线程/回调函数/中断函数的参数,以及这些函数本身的参数,应该很容易找到答案的
-autumn_wind(al);
2013-8-6
(#8320277@0)
-
这个好像有点道理:“静态成员函数存在的原因是什么呢?主要是在建立任何对象之前可用它来访问静态数据成员,普通函数不能实现此功能。”
-leonardmars(小马识途);
2013-8-6
(#8320170@0)