上一课标准答案先给你:
this->speed表示"当前这个Motor对象内部的成员变量speed";右边的speed表示传给setSpeed()的函数参数。
double getSpeed() const
后面的 const 表示:这个成员函数承诺不会修改当前对象的成员状态。
-
选 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();
和哪一句基本等价?