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

C++ 为什么可以将所有类型转换为其他指针类型?,c++,C++,代码: 类虚拟{ 双i,j; }; 类添加{ int x,y; 公众: 加法(inta,intb){x=a;y=b;} int result(){返回x+y;} }; int main(){ 虚拟d; 添加*padd; padd=(加法*)&d; //cout result(); 返回0; } 问题: 为什么您可以这样做padd=(Addition*)&d但不是这个padd=(加法)&d 当声明一个加法对象(如Addition padd而不是Addition*padd)时,为什么它需要构造函

代码:

类虚拟{
双i,j;
};
类添加{
int x,y;
公众:
加法(inta,intb){x=a;y=b;}
int result(){返回x+y;}
};
int main(){
虚拟d;
添加*padd;
padd=(加法*)&d;
//cout result();
返回0;
}
问题:

  • 为什么您可以这样做
    padd=(Addition*)&d但不是这个
    padd=(加法)&d
  • 当声明一个加法对象(如
    Addition padd
    而不是
    Addition*padd
    )时,为什么它需要构造函数,而在声明指针时却没有

获取变量的地址会返回一个指针,这与原始变量截然不同。指针只是一个内存地址(通常大小为
int
),而指向的对象可以是从
char
到大型表或流的任何内容。因此,您可以确定不以非指针类型强制转换指针(反之亦然),并且
(Addition)&d
无法工作

当您键入
Addition padd时,您将构建一个类型为
Addition
的对象,该对象是默认构造函数。当您键入
Addition*padd,您只需声明一个指针,这样就可以创建一个内存地址,而不创建任何对象


最后,注意C转换(变量前面括号中的类型)。这个转换将尝试几个C++的Casic直到它成功(从<代码> StistalPasks到 RealTytCase),并且你可以很容易地发现自己在一个未定义的行为上。例如,请参见。

基本上,您在问对象和指向对象的指针之间有什么区别

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

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

如上所述,所有指针在物理上都是相同的(即整数)。这就是为什么做前者总是可能的。请注意,在结束时,取消引用此指针是未定义的行为。但是,编译器转换为不同的内容(指向存储的指针)似乎是不可行的

当声明一个加法对象时,比如Addition padd而不是Addition*padd,为什么它需要一个构造函数,而在声明指针时却没有

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

顺便说一下,指针也是对象,这就是为什么可以有指向指针的指针等等

此外:

  • 指向
    void
    、对象和函数的指针与指向成员的指针非常不同

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


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

  • 指针就像现实生活中的符号

  • 指向湖泊的标志类似于指向建筑物的标志()。
    指向湖泊的标志与实际的湖泊或建筑物不同

    现在,当你假设一个标志指向一个湖泊,而实际上它指向一座建筑物,你试图把这座建筑物当作一个湖泊(比如在其中游泳),你就会遇到问题

    这是说:C++会运行在不兼容指针之间的代码,但是试图访问你错误地投下的指针指向的对象可能不会对你工作得很好。

  • 制作一个新的标志并不要求你同时制作你想要它指向的东西。
    你可以有一个指向一个湖的标志,而这个湖实际上并不指向一个湖(还没有?),或者你可以将它指向一个现有的湖

&lake
为您提供一个指向
lake
的标志


免责声明:我可能从其他人那里借用了核心思想。

您没有初始化任何字段。指针只是一个数字,告诉您对象应该在内存中的位置。您可以将指针强制转换为任何其他指针,因为每个指针都是完全相同的东西:一个数字(可用于指向内存)。对象和其他数据类型更复杂,不一定彼此兼容。还要记住,仅仅因为可以强制转换指针,并不意味着取消引用它就不会使程序崩溃或调用未定义的行为,因为在这一点上,你会尝试访问C++样式,避免使用C++代码,如“代码> STATICEXCAST 或<代码> DyrimCysCase<代码>,然后你会发现这个代码不编译。每个问题一个问题,我想现在再假设指针大小通常是不合适的。一个
int
。现在,64位已经过时了。是的,我不是指指向成员的指针,如果你是关于这个的,那么你能给出一个提示吗?C++标准给出了很多关于使用错误类型指针时会发生什么的纬度。虽然所有指针都必须可存储在
void*
中,但它允许
char*
大于我上次检查的
int*
(如果您的系统具有dword寻址,但您仍然需要8位char,并且不希望在
int*
上浪费空间,这一点很有用)。简而言之,在大多数台式机上工作的不是C++标准所需要的。“在C++的大多数实现中,您将使用”和CL
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;
}