在 C++ 中使用 nullptr 访问类的成员 [重复]
Posted
技术标签:
【中文标题】在 C++ 中使用 nullptr 访问类的成员 [重复]【英文标题】:Accessing members of class using nullptr in C++ [duplicate] 【发布时间】:2021-01-01 10:34:26 【问题描述】:#include <iostream>
#include <string>
using namespace std;
class Check
public:
int a;
string b;
float c;
void print()
cout << "What!";
Check()
cout << "Constructor has called";
~Check()
cout << "Destructor has called ";
;
int main()
Check* ptr;
ptr->print(); /*How and why is it working without any error or undefined behaviour even though i did not store an address of object in it */
return 0;
我使用的是 Visual Studio 2019 更新版
据我所知,我们可以通过指针访问类的成员,方法是指向类,然后存储该类类型的对象的地址,然后我们可以通过'->'访问成员使用那个指针
【问题讨论】:
为什么你认为这不是未定义的行为?这只是 UB 最坏的情况,它似乎可以工作。 技术上你所做的是UB。由于print()
不对类的成员做任何事情,因此可以合理地预期即使对象是垃圾,它也只会进行打印。这就是 UB 的含义,即无法保证会发生什么 - 也可能会发生一些正确的行为。
未定义的行为意味着该行为未定义,并不意味着它不会“工作”,或者它一定是一个错误。这里定义的意思是由C++标准定义。当您的程序有未定义的行为时,任何事情都可能发生,并且您的编译器没有违反 C++ 标准的任何规则。
【参考方案1】:
据我所知,我们可以通过指针访问类的成员,方法是指向类,然后存储该类类型的对象的地址,然后我们可以通过'->'访问成员使用那个指针
没错。但是,除非您需要,否则您不会使用指针,而只使用对象本身:
Check ptr;
ptr.print();
如何以及为什么它没有任何错误地工作......
您不会收到错误,因为取消引用空指针是未定义的行为。编译器可能会在可以检测到问题的情况下发出警告,但它们不需要发出错误(通常它们不能)。
... 或未定义的行为,即使我没有在其中存储对象的地址
您的代码确实有未定义的行为。未定义的行为意味着您无法保证您的代码会做正确的事情。您确实不会保证您的代码会出错。
在幕后this
指针作为隐式参数传递给成员函数。由于print
实际上并未使用该类的任何成员,因此未使用指针并且您的代码似乎可以工作。然而,这只是偶然。根据语言规则,ptr->print();
已经是未定义的行为(无论 print
是否使用成员)。
【讨论】:
【参考方案2】:大多数 C++ ABI 将 this(您要取消引用的指针)作为隐式的第一个参数。在您的 print 方法调用中,您永远不会引用 this(您的函数不引用对象成员),这就是您的程序不会崩溃的原因。如果引用一个对象成员或使 print virtual 你的方法将崩溃,这是 null。
【讨论】:
以上是关于在 C++ 中使用 nullptr 访问类的成员 [重复]的主要内容,如果未能解决你的问题,请参考以下文章