【问题标题】:C++ class member scope when instatiated object in constructor在构造函数中实例化对象时的 C++ 类成员范围
【发布时间】:2020-10-15 22:28:57
【问题描述】:

我在类构造函数中有这段代码:

MqttSensorInterface::MqttSensorInterface(Client& client, String sensorTopic)
{
  this->mqttClient = PubSubClient(client);
  this->sensorTopic = sensorTopic;
  this->askMeasureTopic = sensorTopic + "/askmeasure";
  this->publishMeasureTopic = sensorTopic + "/measure";
}

但是在创建新的MqttSensorInterface对象时使用构造函数后,在构造函数中实例化的PubSubClient对象被破坏(调用PubSubClient析构函数)。我是 C++ 的新手,不知道这段代码是否有问题。由于PubSubClient对象在构造函数中被实例化,但是类成员mqttClient被设置为这个对象,它的作用域是什么?

PubSubClient 构造函数代码:

PubSubClient::PubSubClient(Client& client) {
    this->_state = MQTT_DISCONNECTED;
    setClient(client);
    this->stream = NULL;
    this->bufferSize = 0;
    setBufferSize(MQTT_MAX_PACKET_SIZE);
    setKeepAlive(MQTT_KEEPALIVE);
    setSocketTimeout(MQTT_SOCKET_TIMEOUT);
}

编辑

通过这种方式使用成员初始化器列表解决:

MqttSensorInterface::MqttSensorInterface( Client& client, String sensorTopic): mqttClient(client)

【问题讨论】:

  • PubSubClient(wifiClient); 创建一个新对象,然后将其复制或移动到成员变量中。当构造函数完成时,原始的被销毁
  • 这取决于PubSubClient::operator=(PubSbuClient const&) 的实现。也许有共享资源?
  • 如果这对您来说是个问题,这只是 favor member initializer lists 在 c'tor 中过度分配的另一个原因。
  • 不,请不要。在超过 300 的声誉下,您应该非常清楚有关您的问题的重要细节(如代码)属于帖子正文,而不是 cmets。 edit 代码进入你的问题。
  • 没有minimal reproducible example 这个问题不清楚。您发布的代码可能很好也可能不好,具体取决于您未发布的代码。我建议你写一个更小的玩具示例并为此提出相同的问题,因为这里缺少太多内容

标签: c++ object constructor scope


【解决方案1】:

当构造函数体时

MqttSensorInterface::MqttSensorInterface(String sensorTopic)
{
  WiFiClient wiFiClient;
  this->mqttClient = PubSubClient(wifiClient);
  this->sensorTopic = sensorTopic;
  this->askMeasureTopic = sensorTopic + "/askmeasure";
  this->publishMeasureTopic = sensorTopic + "/measure";
}

使用默认构造函数PubSubClient获取已经创建的数据成员mqttClient的控制权,前提是在类定义中没有数据成员的显式初始化器,

所以在这个语句的主体内部

this->mqttClient = PubSubClient(wifiClient);

通过显式调用构造函数PubSubClient(wifiClient) 创建了一个PubSubClient 类型的临时对象,并使用复制赋值运算符或移动赋值运算符将此临时对象分配给数据成员this->mqttClient .在语句执行结束时,临时对象被销毁。

如果可能的话,你可以在构造数据成员的过程中,在构造函数的mem-initializer列表中初始化数据成员。

【讨论】:

  • 如果我使用new PubSubClient(wiFiClient),那么在明确销毁之前它不会被销毁,对吧?
  • @MABC 我不明白你的意思。在这个语句中 this->mqttClient = PubSubClient(wifiClient);创建了一个临时对象 PubSubClient(wifiClient);分配给数据成员。分配后临时对象将被销毁。
  • 如果使用此语句this->mqttClient = PubSubClient(wifiClient); 使用此语句this->mqttClient = **new** PubSubClient(wifiClient); 会有所不同?
  • MABC:这些不相等,是的,有区别,但可能不是您想要的区别。创建minimal reproducible example,以便我们获得所需的所有信息。
  • @MABC 当然有区别。如果使用 operator new 则第二种情况无效,因为 this->mqttClient 不是指针是吗?
猜你喜欢
  • 2014-11-28
  • 1970-01-01
  • 1970-01-01
  • 2012-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多