用C++越久,越是觉得C++太多陷阱,真是防不胜防。
我们看这样一段代码:

编译执行正常,结果是:

然后我们改一下,把构造函数变成无参数的:

继续编译执行,输出居然是空了!?

实在找不到任何原因,于是gdb了一下,发现根本就没有到构造函数里面。
再仔细看了一下,想起来一般无参数的类初始化都是没有括号的,于是换了一下调用方法:

结果正常了~

这是神马坑爹的语法?!有参数的时候就要有括号?没参数的时候连个空括号都不能有?

抱怨归抱怨,我们跳出来看一下:

这行语句根本就是一行函数声明啊。。。

试想一下,有一天一个类的构造函数从一个参数变成空参数,于是你在调用的时候只是把括号里的参数删了,而括号还留着的话。。估计够你调几个小时了。。

最近的一些技术整理(20120109)

前段时间一直没写博客,昨天更新了一篇,今天突然又来了兴致,那就再更新一篇吧(所以说啊,治疗拖延症最好的方法就是现在开始做) 这篇还是一些技术的整理,...

阅读全文

C++模板的几个应用

C++的模板其实是个挺纠结的东西,用的不好的话,编译的一堆错误够你调到崩溃,但要是用的好呢,又确实非常方便,我们来看看 一.获取数组长度 比如 ...

阅读全文

代码即数据,数据即代码(1)-把难以变更的代码变成易于变更的数据

相信对于这个标题,用过lisp的朋友一定不陌生,本来也是准备了一大堆理论要讲,想了想还是直接举例子比较好。 就举最近产品提的一个产品需求吧,简单描述一下...

阅读全文

46则回应给“又见C++诡异问题”

  1. WeAiM说道:

    我***。这个,要是没见过,不会想到这个。唉,一方面是对c++越来越不熟悉了,另一方面,这个实在太dt了。

    [回复]

  2. sw说道:

    看看这个:

    int b;
    C x1(C2(b));

    很遗憾的告诉你,这仍然是函数声明 :D

    [回复]

    Dante 回复:

    还真是。。。
    int b;
    C x1(C(b));

    [回复]

  3. 一念天堂说道:

    这个倒是一眼就看出来了,吃过这个亏,我也记得有大牛说过:这是语言的阴暗面之一,我们只能 live with it.

    [回复]

    Dante 回复:

    语义的二义性。。确实如此。。

    [回复]

  4. fanhe说道:

    c++ primer 说过了, 类类型的声明不能这样的初始化语法的.
    c++ 很多细节要注意的, 非常麻烦.

    [回复]

  5. dutor说道:

    倒不觉得奇怪,如果之前是写Java的话就另说了。
    从语法分析的角度来讲,C x1();本就可以有两种解释,只不过C++优先把它当成函数声明罢了。

    [回复]

    Dante 回复:

    我不用java。。
    嗯,语义出现二义性了。

    [回复]

    Fangzhen 回复:

    C++和java不一样,
    C x1()就是一个函数声明,C++中如果要使用默认构造函数(就是不带参数的构造函数)的时候不用加括号。如果要动态构造一个类的话加不加括号都一样,如:
    C * px=new C();
    和C *p=new C;
    是一样的

    [回复]

  6. DJ说道:

    还真遇到过,不过那时候立刻调试了,一下发现没进去就明白是当成声明了

    [回复]

  7. egmkang说道:

    哇,居然还有这个,倒真的没碰到过…………

    [回复]

  8. egmkang说道:

    C++真是到处都是坑啊

    [回复]

  9. Shiina Luce说道:

    ……这是Java写多了吧

    [回复]

    Dante 回复:

    我还真不用java。。

    [回复]

  10. sanitizer说道:

    隐约记得好像C++没参数的时候,推荐使用C(void)的吧?C()算是不规范写法。

    [回复]

    Dante 回复:

    C(void) 也是不行的。。你可以试试。
    void也可以看作是函数形参。

    [回复]

    dutor 回复:

    C里面C()原型可以传参,C++里面C()等价于C(void),这里面如果写成C(void)的话,就告诉编译器这就是原型,编译器就毫不犹豫咯。
    下面的“匿名”兄弟太有喜感了,哈哈哈

    [回复]

  11. 匿名说道:

    你不会用就别乱说,真是笑死人了!你怎么不用C x1=new C();这种方式去初始化C++代码?那岂不是更有喜剧效果?

    [回复]

    shade 回复:

    这位匿名的兄台~
    我觉得你更搞笑一些
    希望你能分享一些有营养的内容~

    [回复]

  12. 匿名说道:

    真搞笑,用其他语言的语法去要求C++

    [回复]

  13. 匿名说道:

    C()调用的是拷贝构造函数,不是无参构造函数。不要在这种基本的问题是误导新手。

    [回复]

    Dante 回复:

    这位朋友,虽然你的几个评论都有点尖锐,但我开始还是不打算回复你的帖子的,但是你非要说C()居然是调用拷贝构造函数这种误导性的话,我只能出来辟谣了。

    C x1;
    C x2(x1);
    C x3 = x1;
    x3 = x2;

    这几行代码,你能正确的说出都调用了什么函数吗?

    [回复]

    Sunday 回复:

    唉,不要和此种人一般见识,无知就算了,出来让别人笑话就是他的问题了 !

    [回复]

    Dante 回复:

    哈哈,多谢支持~~~~

    [回复]

  14. Huarong说道:

    一直都用new的飘过。

    [回复]

  15. niuniu说道:

    哈哈 还真是如此~
    如果C++滴水不漏,就不会有其他语言了~

    [回复]

  16. 1901说道:

    上帝保佑我以后不要遇到这个问题,我经常写AS的啊!

    [回复]

  17. dreamersdw说道:

    我写C++代码时,只能每增加一行,就运行一次g++。对了,还要打开http://en.cppreference.com/w/cpp 方便查找函数名,头文件。还有当写下 template 后,只能祈求苍保佑不要出错,否则我会被淹没在上千字节的错误信息中。开发效率可想而知。

    《Effective C++》、《More Effective C++》、《Exceptional C++》、《More exceptional C++》、《Effective STL》、《Imperfect C++》、《Essential C++》….. 这个书单可以很长很长。有人说十年才可以学会C++,可要真是花十年在一门语言上,你还有多少时间研究算法。研究设计。

    C++ 的确开发出了很多重要的软件,但这并不足以说这门语言有多好,要知道WordPress 还是用PHP写的呢。

    当我学习过 Haskell 之后,才发现C++中的精华——STL,只是在模仿函数式语言中最基础的部分,而且还没有模仿好(甚至每写一个foreach 都要写一个对应的 functor,鬼才知道那个functor 还能不能复用)

    用Python, Ruby, Haskell,也许是 Java 写程序,必要时调用 C++ 的 library 或许是当下不错的选择。

    用的时间越长,对这种语言越反感,只想说 I hate C++

    [回复]

    Dante 回复:

    确实如此,说C顶多砸到脚,C++不小心就会炸飞整条腿的比喻真是非常贴切。

    我现在写自己的东西都是python,简洁优雅。

    可惜公司代码只能用C++,无奈。。。

    [回复]

    springlie 回复:

    貌似这个问题在Effective 系列中提过。。。

    [回复]

    t.w. 回复:

    这个问题我也奇怪过
    原来果然是和函数声明一样啊

    [回复]

  18. 夜弓说道:

    嗯,在c++里面,一个语句如果可以是函数声明,那么它就是函数声明。

    [回复]

    Sunday 回复:

    应该是这么回事~C++时间越长,越觉得杯具~

    [回复]

  19. johnson说道:

    第一个你定义析构函数但是没有定义复制构造函数和赋值操作符,所以你无论你是 C x1(5),还是 C x1(1)值,对象的值是一样的。
    实验方法是
    你定义一个
    C x1(1)
    C x2(5)
    你销毁 X1,C对象也将被销毁
    x2也将不复存在
    第二个
    C x1(),无参数默认为空初始化,输出肯定为空啊
    为什么等于 7 和你 你此句代码有关printf(“%d\n”, __LINE__);

    [回复]

    Dante 回复:

    朋友,你还是再回去看看C++的书吧。

    [回复]

  20. t.w.说道:

    这个问题我也奇怪过,看了你的才理解原因,原来果然是和函数声明一样啊~

    [回复]

  21. t.w.说道:

    这个问题我也奇怪过,看了你的才理解原因,原来果然是和函数声明一样啊

    [回复]

  22. t.w.说道:

    这个问题我也奇怪过,
    看了你的才理解原因,
    原来果然是和函数声明一样啊

    [回复]

  23. xheruacles说道:

    Declaring a class instance using a default constructor that has parameters, you should pass the arguments to let the compiler to correctly construct the object. Declaring a class instance using a default construtor that has no parameters is the same as declaring a variable, since the compiler already knows which constructor to run for you. Overloading allows the flexibilities at the cost of attention of class users to specify the exact function to run.

    [回复]

  24. Terrence说道:

    的确如此,有些时候人的视角和编译器的视角是不是不一致的。习惯就好~

    [回复]

  25. IMS说道:

    如果函数声明使用了C(void){}这样呢?

    [回复]

  26. cplusplusisapieceofshit说道:

    之前学过一点c++皮毛,然后学过java之后想再回头好好学习下c++,因为觉得c++还是很牛的,但每次看个开头就看不下去了,相比java,c++就是一坨屎一样的恶心。

    [回复]

  27. lssb说道:

    C++是一门优秀的语言,优秀不代表完美,总会存在或多或少的不习惯。但C++能流行30多年,足以说明一切问题了, ls的那个不懂就不要在那装B ,你说的话更相一坨屎

    [回复]

  28. d说道:

    第一次遇到这个是在面试的时候,于是面试惨败

    [回复]

  29. haoaina521说道:

    看完评论才知道这是函数声明,并不是有参数和无参数的区别。向楼主请教两个问题,如果问题有错,麻烦指出下:1.C c;这句语句是变量的定义?在定义的时候初始化了?2.C* pC1 = new C;和C* pC2 = new C();有什么不同?

    [回复]

  30. helloworld说道:

    求教,为什么是函数声明?另外,这句代码的原义是以b为参数构造一个C的对象,然后调用拷贝构造函数创建x1吗?

    [回复]

发表评论