在上 coursea 的 C++课程,颠覆了以前 C 编程中的看法。
#include <iostream>
using namespace std;
class A{
int i;
public:
void Hello(){ cout << "hello" << endl; }
};
int main(){
A * p = NULL;
p->Hello();
return 0;
}
这玩意的编译输出是 hello。这样真的好吗。。。
1
zts1993 2017-09-11 20:53:28 +08:00
这个有点颠覆我的认知: 这个不会 core 么??
|
2
jlsk 2017-09-11 21:04:35 +08:00
正常,你把 Hello()改成 cout <<i<< endl;就知道错了
|
3
03 2017-09-11 21:07:55 +08:00
对于标题:这都什么时候的事情了
https://stackoverflow.com/questions/2505328/calling-class-method-through-null-class-pointer 一样 这样很好啊,反正你的 Hello()不与具体对象相关,直接就解释为调用那个函数不就可以了,反正对一个无效指针调用是你的责任而不是 C++有义务检查 |
4
douglas1997 OP @jlsk 这个我知道,关键是这样去实现是不是不太好?(不太直觉)
|
5
douglas1997 OP @zts1993 不 core 不 core hhh
|
6
zmj1316 2017-09-11 21:28:11 +08:00
这个和 C 有什么关系...虽然传进去的 this 是个 null ,反正又没调用到,你的函数要是个虚函数应该就跪了
|
7
acros 2017-09-11 21:34:27 +08:00 via iPhone
为啥会有这种写法,是为了教学说明类的内存布局吧?
|
8
secondwtq 2017-09-11 21:36:32 +08:00 3
如果你对 C++ 足够熟悉,那么你可以以相对直接的方式把 C++ 程序翻译成等效的 C 程序。最早的 C++ 编译器就是这么干的。
之所以强调 相对直接,是因为在 Compiler 中,C 语言实际上相当于高级汇编,最近几年比较流行 codegen 编译到 LLVM IR,实际上更早的时候有不少是编译到 C 语言的,比如 GHC 最后一层的 IR 叫 C--,Gnome 的 Vala 也是这么干的 如果不计较这个编译过程的逻辑和复杂性,以及运行时系统的介入程度的话,JS 都可以编译到 C。对于 C++ 自己的体量和设计来说,翻译到 C 的过程(尤其是楼主所用的这个子集)是相对直接的。 详见 https://isocpp.org/wiki/faq/compiler-dependencies#convert-to-c 对于一个要与 C 争市场的语言来说,“这么实现”是完全没问题的。“不太好”的反而在于楼主的用法,一般 C++ 不提倡 hack,尤其是这种会 UB 的 hack。 建议楼主可以多看看出来的汇编,还有 Inside the C++ Object Model 这种书,了解了一个特性,可以多想一步这个是怎么实现的。 这里其实有一个坑。学一门语言,我认为最重要的是一方面学它的 principle,另一方面学 application。楼主有必要在学之前了解一下 C++ 的一些基本的特点,很简单:directly mapped to hardware, 还有 zero cost abstraction。楼主如果单一地照这条路走下去,很有可能会只记得前者,而忘了后者。因为 C++ 是以 directly mapped to hardware 以及与 C 语言兼容(至少是一开始)为原则而设计的,所以可以相对简单地翻译成 C 语言,但是不代表你把 C++ 代码翻译成 C 代码没问题了,C++ 代码就没问题了。如果不明白 abstraction 那一部分,那实际上没有太多用 C++ 的意义。 如果发现自己在问 std::optional 有什么意义,Template Metaprogramming 有什么用这种问题的时候,说明该去学 Haskell 压压惊了(逃 |
9
acros 2017-09-11 21:37:53 +08:00 via iPhone
另外你说这个反直觉我认可,颠覆 c 的认识? hmmmm 看来没见过 c 里面,0 地址强转 struct 指针求成员 offset 的那个方法。
|
10
gamexg 2017-09-11 22:11:11 +08:00 via Android
go 这样干也行,也是你只要不访问成员变量随你玩,访问了就,来😇了
|
11
admos 2017-09-11 22:31:04 +08:00 via iPhone
这东西各种都是 trival 的,是 POD 类型的按 c 来怎么了,还省了各种乱七八糟的呢。
|
12
douglas1997 OP @secondwtq 非常感谢前辈指导。
|
13
geelaw 2017-09-12 07:17:11 +08:00
这个程序的行为不是确定的啊,因为里面有 UB,编译器可以产生一个什么都不干的程序,也可以产生恰好输出 Hello 的程序。
|