为什么可以将所有类型转换为其他指针类型?

时间:2017-06-09 10:42:17

标签: c++

代码:

class Dummy {
    double i,j;
};

class Addition {
    int x,y;
  public:
    Addition (int a, int b) { x=a; y=b; }
    int result() { return x+y;}
};

int main () {
  Dummy d;
  Addition * padd;
  padd = (Addition*) &d;
  //cout << padd->result();
  return 0;
}

问题:

  • 为什么可以执行此操作padd = (Addition*) &d;而不是padd = (Addition) &d;
  • 当声明像Addition padd而不是Addition* padd这样的加法对象时,为什么要求构造函数,在声明指针时它不会?

3 个答案:

答案 0 :(得分:0)

获取变量的地址会返回一个指针,这与原始变量完全不同。指针只是一个内存地址(通常是int的大小),而指向的对象可以是从char到巨大的表或流的任何内容。因此,您最终可以不在非指针类型中强制转换指针(反之亦然),(Addition) &d无效。

当您键入Addition padd;时,您构建了一个类型为Addition的对象,它是默认构造函数。键入Addition* padd;时,只需声明一个指针,即内存地址,也不会创建任何对象。

最后,要小心C cast(变量前面的括号中的类型)。这个演员将尝试几个C ++演员,直到它成功(从static_castreinterpret_cast),你很容易发现自己处于未定义的行为。例如,请参阅this

答案 1 :(得分:0)

基本上你问一个对象和指向对象的指针有什么区别?

对象是存储区域。指针只是指向此存储中的偏移量的整数。物理上的指针(在用代码生成二进制代码之后)与一种类型的对象与另一种类型的对象没有区别 - 总是一个整数。另一方面,对象是具有偏移和大小的区域。 C ++区分的两个基本问题。

  

为什么你可以这样做padd =(Addition *)&amp; d;但不是这个padd =(加法)&amp; d;?

如上所述,所有指针在物理上都是相同的(即整数)。这就是为什么始终有可能做前者。请注意,最后解除引用此指针是未定义的行为。但是,编译器似乎不可能转换为不同的事物(指向存储的指针)。

  

当声明像Addition padd这样的Addition对象而不是Addition * padd时,为什么要求一个构造函数,在声明指针时它没有?

再次指针只是一个整数,你不需要任何其他东西来创建它。但是,Addition是一个存储shat类型,没有默认构造函数,这就是为什么你必须提供其他对象来初始化它。

顺便说一句,指针也是对象,这就是为什么你可以有一个指针指针等的原因。

另外:

  • 指向void的指针,对象,函数与指向成员的指针有很大不同;

  • 指向void,对象,函数的指针不得假设具有固定大小,大小可能在某些平台,编译器上有所不同,但不大于void*

答案 2 :(得分:0)

一个间接回答你问题的简单明喻:

  • 指针就像现实生活中的标志。

  • 指向湖泊的标志类似于指向建筑物的标志(but you can also use a different definition of "similar" which will say these things aren't similar)。
    指向湖泊的标志与实际的湖泊或建筑物不相似。

    现在当你假设一个标志指向一个湖泊时,它实际上指向一个建筑物,并且你试图将这个建筑物视为一个湖泊(例如游泳),你就会遇到问题。 / p>

    也就是说:C ++会运行在不兼容的指针之间进行转换的代码,但是试图访问你错误转换的指针指向的对象可能不会对你有效。

  • 制作新标志并不要求您也要制作想要指向的东西 你可以在一个实际上没有指向湖泊的湖泊上签名(但是?),或者你可以将它指向现有的湖泊。

&lake为您提供lake的签名。

免责声明:我可能已经从其他人那里借用了核心理念。