C++中“箭头(->)”和“点号(.)”

发布于 2024-04-27  48 次阅读


C++中“箭头(->)”和“点号(.)”

例子:

#include <iostream>
#include "string"

class W {
public:
    int age = 10;
};

int main() {
    W n;
    n.age = 17;//与java类似
    std::cout << n.age << std::endl;
    W *nn = new W;//指向 `W` 类型的指针
    nn->age = 15;
    std::cout << nn->age << std::endl;
    (*nn).age = 16;
    std::cout << nn->age << std::endl;
}

如果有个MyStruct(类名) s(对象名),那么使用其中的成员元素时可以用:

s.member_a = 1;

如果采用指针方法访问,比如MyStruct * ps,那么同样的访问就必须使用如下形式:

(*ps).member_a = 1;

或者

ps->member_a = 1;

c++中当定义类对象是指针对象时候,就需要用到对象名->指向类中的成员;当定义一般对象时候时就需要用到"."指向类中的成员。

如果定义如下:

MyStruct *p则使用:p->play(); 左边是对象指针。

MyStruct p 则使用:p.paly(); 左边是对象变量。

总结:

箭头(对象名->指向类中的成员):左边必须为指针对象;

点号(对象名.类中的成员):左边必须为实体。

箭头(对象名->指向类中的成员)的本质就是((*对象名).类中的成员)

还有一种更优雅的用法

当一个类用另一个类的时候

#include <iostream>

class Jian {
private:
    char *name;
public:
    Jian(char *name)
            : name(name) {
    }

    void getName() {
        std::cout << name << std::endl;
    }
};

class ScopedPtr {
private:
    Jian *teat;
public:
    ScopedPtr(Jian *trat)
            : teat(trat) {
    }

    ~ScopedPtr() {
        delete teat;
    }

    Jian *getJian() {//方法一(不优雅)
        return teat;
    }

    Jian *operator->() {//优雅方法二
        return teat;
    }
};

int main() {
    ScopedPtr teat = new Jian("ranfey");
    teat.getJian()->getName();//方法一(不优雅)
    teat->getName();//优雅方法二
}

接下来是Cherno的表演---不寻常的方法来确定结构体成员的偏移量

  1. (Vector3*)nullptr:将空指针(nullptr)强制类型转换为Vector3类型的指针。这本身没有意义,因为指针是空的,但它允许我们通过这个空指针来访问Vector3类型的成员。

  2. ->y:通过箭头操作符->来访问Vector3结构体指针指向的y成员。

  3. &:取地址操作符,获取y成员的地址。

  4. (int):将地址强制类型转换为int,这样我们就得到了y成员相对于结构体起始地址的偏移量(以字节为单位)。

在大多数架构中,结构体成员是按照它们在结构体定义中的顺序紧密排列的,所以这段代码应该输出y成员相对于Vector3结构体起始地址的偏移量。

#include <iostream>
#include <string>

struct Vector3
{
    float x, y, z;
};

int main()
{
    int offset = (int)&((Vector3*)nullptr)->y;
    std::cout << offset << std::endl;

    std::cin.get();
}
QQ:2219349024
最后更新于 2024-04-27