在 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-&gt;print(); 已经是未定义的行为(无论 print 是否使用成员)。

【讨论】:

【参考方案2】:

大多数 C++ ABI 将 this(您要取消引用的指针)作为隐式的第一个参数。在您的 print 方法调用中,您永远不会引用 this(您的函数不引用对象成员),这就是您的程序不会崩溃的原因。如果引用一个对象成员或使 print virtual 你的方法将崩溃,这是 null。

【讨论】:

以上是关于在 C++ 中使用 nullptr 访问类的成员 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

C++ 使用变量访问类的公共成员

让公共成员变量访问 C++ 中同一类的私有成员

在 Cython 中访问 C++ 类的私有成员变量/函数

C++ 类的继承一(访问控制)

[C++][linux][原创]让类的成员变量可以在类的静态函数中访问

[C++][linux][原创]让类的成员变量可以在类的静态函数中访问