Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在不强制转换的情况下,使用不同数据类型的地址分配指针_C++_Pointers - Fatal编程技术网

C++ 在不强制转换的情况下,使用不同数据类型的地址分配指针

C++ 在不强制转换的情况下,使用不同数据类型的地址分配指针,c++,pointers,C++,Pointers,我以前从未见过这种代码: (B类是a类的一个子类) 问题1: 为什么这个作业是有效的 与之相比有什么区别 Class B objB; Class A *ptrA; ptrA = (ClassA*)&objB; 或 问题2: 这一行也是有效的。虽然这个概念看起来和前一个非常相似,但我不知道它是如何工作的 可以告诉我为什么这些赋值是有效的吗?< /P> < P> C++中的基类指针可以指向派生类的一个单位。这个语言规则使这些语句在C++中有效。 首先,这是允许的,因为这不会产生任何问题,因

我以前从未见过这种代码:

(B类是a类的一个子类)

问题1:

为什么这个作业是有效的

与之相比有什么区别

Class B objB;
Class A *ptrA;
ptrA = (ClassA*)&objB;

问题2:

这一行也是有效的。虽然这个概念看起来和前一个非常相似,但我不知道它是如何工作的


可以告诉我为什么这些赋值是有效的吗?< /P> < P> C++中的基类指针可以指向派生类的一个单位。这个语言规则使这些语句在C++中有效。 首先,这是允许的,因为这不会产生任何问题,因为使用基类指针访问oblect不会访问任何未定义的内存或函数。因为在基类中定义的任何内容也在子类/派生类中定义。

此功能允许
动态多Marphism
。其中,派生类可以实现不同的功能,单个基类指针将调用派生类对象的函数,并根据基类指针指向的对象类型调用函数。如果不允许基点指针派生类对象并调用函数,则此特性是不可能的。C++中的< /P> < P>基类指针可以指向派生类的一个母形。这个语言规则使这些语句在C++中有效。 首先,这是允许的,因为这不会产生任何问题,因为使用基类指针访问oblect不会访问任何未定义的内存或函数。因为在基类中定义的任何内容也在子类/派生类中定义。

此功能允许
动态多Marphism
。其中,派生类可以实现不同的功能,单个基类指针将调用派生类对象的函数,并根据基类指针指向的对象类型调用函数。如果不允许基指针指向derivd类对象和调用函数,则无法实现此功能。

这称为多态性。它是所有面向对象编程语言最重要的关键特性之一


多态性意味着如果
B
是从
A

派生出来的,那么
B
类型的实例可以被视为
A
类型的实例,这称为多态性。它是所有面向对象编程语言最重要的关键特性之一

ClassA *ptrA = &objB; // Question1
多态性意味着如果
B
是从
A
派生出来的,则类型
B
的实例可以被视为类型
A
的实例

ClassA *ptrA = &objB; // Question1
为什么这个作业是有效的

因为多态继承就是这样工作的。A
ClassB
是A
ClassA
;因此,指向
ClassB
的引用/指针可以转换为指向
ClassA
的引用/指针

ptrA = (ClassA*)&objB;
这是做同样的事情,但使演员显式。然而,这更危险——邪恶的C样式转换将允许任何指针转换,不管它是否有效,而原始的隐式转换将只允许安全转换(就像派生到基指针的转换一样)

创建一个动态对象,给你一个指向该对象的指针;原始对象将指针设置为指向现有对象。除非你真的需要,否则不要使用
new

ClassA objA = *ptrA // Question2
这有时被称为切片。如果基类是可复制的(这里大概就是这样),那么可以复制基子对象以生成该类型的新对象。从技术上讲,
*ptrA
被转换为对
ClassA
的引用(因为这样的转换是允许的,就像前面的指针转换一样);然后,该引用用于复制初始化
objA

切片会造成混乱;但如果只使用抽象基类,这不是问题,因为它们不能直接实例化

为什么这个作业是有效的

因为多态继承就是这样工作的。A
ClassB
是A
ClassA
;因此,指向
ClassB
的引用/指针可以转换为指向
ClassA
的引用/指针

ptrA = (ClassA*)&objB;
这是做同样的事情,但使演员显式。然而,这更危险——邪恶的C样式转换将允许任何指针转换,不管它是否有效,而原始的隐式转换将只允许安全转换(就像派生到基指针的转换一样)

创建一个动态对象,给你一个指向该对象的指针;原始对象将指针设置为指向现有对象。除非你真的需要,否则不要使用
new

ClassA objA = *ptrA // Question2
这有时被称为切片。如果基类是可复制的(这里大概就是这样),那么可以复制基子对象以生成该类型的新对象。从技术上讲,
*ptrA
被转换为对
ClassA
的引用(因为这样的转换是允许的,就像前面的指针转换一样);然后,该引用用于复制初始化
objA


切片会造成混乱;但如果只使用抽象基类,这不是问题,因为它们不能直接实例化。

关于问题2,这里有两种可能的结果:

ClassA *ptrA = &objB;  
ClassA objA = *ptrA;   // Question2
  • 若不存在复制运算符,则只复制ClassA a范围中的数据字段,其余数据将丢失。这可能有潜在的危险,因为可能会复制虚拟类的错误vtable。这被称为
  • 如果存在ClassA::operator=(const ClassA&rhs),则问题会自行解决。只需确保在copy操作符中实现正确的逻辑即可
  • 如果您不特别注意为类编写正确的复制逻辑,那么您的代码肯定会在运行时中断。我真的推荐“有效C++”,如果你还没有把它捡起来,它给C++的世界提供了一个很好的捷径。