c-function.c:


/* This is C code */
 
 #include "Fred.h"
 
 void c_function(Fred* fred)
 {
   cplusplus_callback_function(fred);
 } 


  和c++代码不一样,c代码不能辨别两个指针指向相同的对象,除非指针的类型是相同的。例如,在c++很容易检查是否一个被称为dp的类型为Derived*的指针是否和一个称为bp的类型为Base*的指针指向相同的对象,仅仅写if (dp == bp)可以。c++编译器自动将两个指针转换成相同的类型,在这个例子中转换成Base*,然后比较它们。依赖于c++编译器的实现,有时这种转换会修改指针的值。

  (技术旁注:大多数c++编译器使用二进制对象布局来达到多继承和虚继承时的转换。但是c++语言并不强制对象布局,所以理论上即便没有虚的单继承也可能发生转换。)

  很好理解:c编译器不知道怎么做那种指针的转换,所以从Derived*到Base*的转换要在c++编译的代码中做,而不能再c编译的代码中做。

  注意:将那两个指针转换成void*时一定要非常小心,因为c和c++编译器对这种情况都不能做适当的指针调整。即便(b==d)为真时(x==y)的比较也可能为假:


void f(Base* b, Derived* d)
 {
   if (b == d) {    Validly compares a Base* to a Derived*
     ...
   }
 
   void* x = b;
   void* y = d;
   if (x == y) {    BAD FORM! DO NOT DO THIS!
     ...
   }
 } 


  像上面描述的,上述指针转换一般发生在有多继承或者虚继承时,但是请不要把它们看做指针转换发生的情况。

  如果你真的想用void*指针做比较,安全的方法是:


void f(Base* b, Derived* d)
 {
   void* x = b;
   void* y = static_cast<Base*>(d);  ← If conversion is needed, it will happen in the static_cast<>
   if (x == y) {    Validly compares a Base* to a Derived*
     ...
   }
 } 
  9、c函数是否可以直接访问一个c++代码中对象的数据

  有时在c++类满足下面情况时,你可以从c函数中直接安全的访问c++对象:

  ● 没有虚函数(包括继承的虚函数)

  ● 所有的数据在同一访问级别(private/protected/publlic)

  ● 没有完全包含的子对象包含虚函数

  如果c++类有子类(或者任何完全包含的子对象有子类),访问数据从技术上讲是不可移植的,因为类的继承布局不是语言硬性规定的。但是在实际中,所有的c++编译器都用了相同的实现技术:父类对象在开始的位置(在多继承的情况下是从左到右的顺序),然后是成员对象。

  另外,如果类(或者任何父类)包含任何虚函数,几乎所有的c++编译器都在第一个虚函数的地方或者是对象的开始的地方放了一个void*。这也不是语言要求的,而是实践中大家遵循的做法。

  如果类有虚父类,它更加复杂和不可移植。一种相同的做法放包含虚基类(v)的对象在后(无论在继承机构中v在哪里成为虚基类)。该对象的其它部分以正常的顺序部署。每一个用v为虚基类的子类都有一个指向后对象的v部分的指针。

  10、为什么我觉得C++对于c更加远离机器

  因为的确如此。

  作为一个oo程序语言,c++允许你对于问题域自己进行建模,从而你可以在问题域中进行编程,而不是在解决域中编程。

  c的有力的方面之一是它没有隐藏的机制。你可以读c程序并看每一个时钟周期都做了什么。在c++中不是这样;对于很多以前从事c的程序员(好像我们中的很多人)对这一功能怀有矛盾的心情(或者可以说“敌视”?)。但是当他们转到用OO的方式思考后,他们发现c++在隐藏了一些机制的同时,也提供了抽象和表达的经济,它们降低了维护的代价,但是有没有损害性能。

  实际上,你可以用任何语言写出坏的代码,c++ 并没有保证任何代码的质量,可重用性,抽象,或者任何其它可以用来评价好的东西。

  c++并没有想防止坏的程序员写出坏的代码;但是它使好的程序员可以写出的代码。