C++ 第 26 课:对象、指针与 ->

上一课标准答案先给你:

  1. this->speed 表示"当前这个 Motor 对象内部的成员变量 speed";右边的 speed 表示传给 setSpeed() 的函数参数。
复制代码
double getSpeed() const

后面的 const 表示:这个成员函数承诺不会修改当前对象的成员状态。

  1. 选 B:

    p->setSpeed(10);

因为 p 是指针。

复制代码
robot.getState()

表示:调用 robot 对象自己的 getState() 成员函数,并取得它返回的状态。


第 26 课:对象、指针和 ->

今天其实就是把你已经学过的两块拼起来:

复制代码
对象 + 指针

先定义一个最简单的类:

复制代码
#include <iostream>

class Robot
{
public:
    void stop()
    {
        std::cout << "Robot stopped" << std::endl;
    }
};

然后创建对象:

复制代码
Robot robot;

你已经知道可以:

复制代码
robot.stop();

这里:

复制代码
robot
↓
一个真正的 Robot 对象

.
↓
访问对象成员

stop()
↓
成员函数

1. 如果我保存的是对象地址呢?

我们已经学过:

复制代码
int x = 5;
int* p = &x;

同样的思想也可以放到对象上:

复制代码
Robot robot;

Robot* p = &robot;

拆开看:

复制代码
&robot

表示:

robot 对象在内存中的地址。

而:

复制代码
Robot* p

表示:

p 是一个指针,它可以保存 Robot 对象的地址。

所以:

复制代码
Robot* p = &robot;

可以画成:

复制代码
p
┌─────────────┐
│ robot的地址  │
└──────┬──────┘
       │
       ▼
    robot
┌─────────────┐
│ Robot对象   │
│ stop()      │
└─────────────┘

2. 普通对象使用 .

如果手里就是对象:

复制代码
Robot robot;

调用:

复制代码
robot.stop();

使用:

复制代码
.

3. 对象指针使用 ->

如果:

复制代码
Robot* p = &robot;

调用对象成员:

复制代码
p->stop();

这里使用:

复制代码
->

所以先形成条件反射:

复制代码
对象
↓
.

对象指针
↓
->

例如:

复制代码
robot.stop();

和:

复制代码
p->stop();

都可以操作同一个 robot。


4. -> 到底干了什么?

你已经学过:

复制代码
*p

表示:

顺着指针找到它指向的对象。

所以理论上:

复制代码
p->stop();

可以理解成:

复制代码
(*p).stop();

这两个表达的核心意思一样。

拆开第二种:

复制代码
*p

先找到 p 指向的 Robot 对象。

然后:

复制代码
(*p).stop()

调用这个对象的 stop()。

因为这种写法太常见了,所以 C++ 提供了更方便的:

复制代码
p->stop();

因此你可以记:

复制代码
p->成员
≈
(*p).成员

5. 成员变量也一样

例如:

复制代码
class Motor
{
public:
    double speed = 0.0;
};

创建:

复制代码
Motor motor;

Motor* p = &motor;

对象可以:

复制代码
motor.speed = 100.0;

指针可以:

复制代码
p->speed = 100.0;

最终改的都是:

复制代码
motor.speed

6. 完整程序

复制代码
#include <iostream>

class Motor
{
public:
    void setSpeed(double speed)
    {
        this->speed = speed;
    }

    double getSpeed() const
    {
        return speed;
    }

private:
    double speed = 0.0;
};

int main()
{
    Motor motor;

    Motor* p = &motor;

    p->setSpeed(100.0);

    std::cout << p->getSpeed() << std::endl;

    return 0;
}

输出:

复制代码
100

执行过程:

复制代码
Motor motor
↓
创建 motor 对象

Motor* p = &motor
↓
p 保存 motor 的地址

p->setSpeed(100)
↓
顺着 p 找到 motor
↓
调用 motor 的 setSpeed()
↓
speed = 100

p->getSpeed()
↓
返回 100

7. 那什么时候会大量遇到 ->?

以后 ROS2 里你会很快遇到。

比如类似:

复制代码
node->create_publisher(...)

或者:

复制代码
publisher_->publish(msg);

这时候不要一看到 -> 就慌。

第一反应就是:

左边这个东西是个指针,右边是在访问它指向对象的成员。

这已经够你阅读很多代码了。


8. 后面还会出现智能指针

例如 ROS2 C++ 代码里非常常见:

复制代码
std::shared_ptr<Robot> robot;

甚至:

复制代码
std::shared_ptr<rclcpp::Node>

然后:

复制代码
robot->stop();

本质思想还是:

robot 里面保存/管理一个对象,然后通过 -> 访问它。

只不过:

复制代码
std::shared_ptr

会帮你管理对象生命周期。

我们后面会专门学:

复制代码
new/delete
智能指针
shared_ptr
unique_ptr

而且对于 ROS2,这部分必须学。


9. 本课练习

复制代码
class Robot
{
public:
    void run()
    {
    }
};

Robot robot;
Robot* p = &robot;

那么请思考:

复制代码
robot.run();

和:

复制代码
p->run();

有什么关系?

另外:

复制代码
(*p).run();

和哪一句基本等价?

相关推荐
青山木37 分钟前
Hot 100 --- 编辑距离
java·数据结构·算法·leetcode·动态规划
长弓三石41 分钟前
把 AgentScope Harness 装进 RuoYi-Vue-Plus:纯 Java AI 平台的集成实践
java·人工智能·agent
蜗牛互联网43 分钟前
MongoDB Atlas Agent Engine之后,如何用版本门禁防止陈旧写入
java·数据库·人工智能·后端·mongodb
长弓三石44 分钟前
企业级智能体的权限到底怎么落地?以 BizBuddy 为例
java·人工智能·agent
用户4270276726811 小时前
一次缓存优化:SQL 从 502 降到 5
java
2601_962885721 小时前
如何用 Python 做股价历史分位选股?(筛出处于历史低位的股票)
开发语言·python
小师兄吃牛肉1 小时前
C语言指针进阶全解析
java·c语言·算法
Joy T1 小时前
聊天系统中五大ID的演进与实战解析
java·前端·人工智能·spring·agent入门
JAVA面经实录9172 小时前
线上故障标准处理流程【完整版|面试背诵+生产落地】
java·面试·职场和发展