在C++中,我们可以解引用this指针吗?如果可以,那么如何操作?如果不行,为什么?

4

我正在用类来进行一个个人项目的开发,但是不想手动初始化每个数据成员。所以在构造函数中调用了 *((Classname *)(this)) = {};。希望它能按照我预期的方式运作。

#include <iostream>

struct Test1
{
    int data1;
    int data2;

    void print()
    {
        std::cout << data1 << ' ' << data2 << std::endl;
    }
};


class Test2
{
    int data1;
    int data2;

    public:
    Test()
    {
        *(Test *)(this) = {};
    }

    void print()
    {
        std::cout << data1 << ' ' << data2 << std::endl;
    }
};

int main()
{
    Test1 t1;

    t1 = {}; /* I wanted the *((Classname *)(this)) = {}; to behave this way 
              * i.e. being able to initialise members with a initialisation list*/


    t1.print();

    Test2 t2;

    t2.print();

    return 0;
}

尽管没有产生编译错误,但是创建Test2对象时会导致分段错误。



是否有另一种初始化所有数据成员为0的方式,或者我们不能在初始化列表中使用this吗?如果是这样,为什么?还是我无意中遇到了未定义的行为?



[如果它是编译器相关的,请注意,我正在使用gcc编译器(gcc版本7.5.0(Ubuntu 7.5.0-3ubuntu1〜18.04))]


3
请解释一下 *(Test *)(this) = {}; 应该做什么。这种方式初始化成员不太清楚。预期的输出是什么? 这行代码使用空花括号初始化 *(Test *)(this) 所指向的对象,即当前对象的所有成员变量将被初始化为它们各自类型的默认值。这句代码的预期输出是没有输出,而是在当前对象中初始化所有成员变量。 - 463035818_is_not_a_number
3
FYI:自C++11以来,您可以删除该构造函数并使用默认初始化程序声明成员,例如:int data1 = 0; - UnholySheep
4
你的构造函数引起了无限递归,因为它自己调用了自己:演示链接。花括号 {} 创建了一个类型为 Test 的临时对象,并通过默认构造函数进行初始化,然后运行了={},接着... - Daniel Langr
3
请注意,这是 XY 问题 的一种较为温和的形式。你的问题涉及到了你认为是解决方案的某个事物,但实际上并非如此。最好询问你想解决的实际问题:如何初始化所有成员变量。this 可以被取消引用,但这并不是你代码中的问题。 - 463035818_is_not_a_number
你的实际问题是:“如何将类的所有成员初始化为零值?”吗? - 463035818_is_not_a_number
显示剩余7条评论
1个回答

6
更新:我刚意识到您修改了代码,现在新的代码不再有意义。我的回答与原始代码相关。 是的,您可以解引用this并调用其成员函数,例如this->f();,它与(*this).f()相同。类似地,(*this) = ...等同于this->operator=(...);
问题在于(*this) = {};会导致创建一个类型为Test的临时变量,并通过默认构造函数进行初始化。因此,您在默认构造函数内调用了默认构造函数,这会导致在您的情况下永远不会结束的递归。
如果要默认将成员变量初始化为零(即如果未在构造函数成员初始化列表中另有规定),只需使用(自C++11起):
int data1 = 0;
int data2 = 0;

谢谢!这解决了我为什么会出现错误以及如何初始化数据成员的问题。 - Nitesh Meena
@NiteshMeena 您好,欢迎来到 Stack Overflow。如果您对这个答案满意,请不要忘记“接受”它,以便让其他人知道这个问题已经解决。 - Daniel Langr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接