C++ 11 - 修改结构向量中的结构成员
C++ 11 - Modifying members of a struct in a vector of structs
我已经在其他地方和此处搜索过执行此操作的方法,但没有找到任何解决我的问题和疑虑的答案。
约束条件:
- 我在 嵌入式 设备上使用 C++ 11。
- 我不会用
std::string
- 我不能用
std::make_unique()
(但我可以用std::unique_ptr
和new
)
- 我不会用
strcpy_s()
我遇到的问题
我遇到的主要问题是,在 AvailableZones::upsertZone
方法中,我想向矢量添加一个区域(如果它尚不存在)(使用名称参数作为 "key").如果存在,我想更新该区域的温度和湿度成员。 "adding" 部分有效,但是更新部分无效。
我的下一期是 AvailableZones::findZone
会员。我希望能够 return 一个区域,以便调用者不对 freeing/deleting returned 值负责。
顾虑:
作为 C++ 的新手,我很确定我没有以正确的 C++11 方式做很多事情。我对 any/all 指导持开放态度(实际上是渴望)。
在 AvailableZones::findZone
方法中,我想要 return Zone
而不是创建副本或使用 new
/malloc
。看来我需要使用常规 for
/while
循环?我看过一些迭代器代码,但它看起来很像 confusing/complicated 但我不确定使用迭代器是否也能解决这个问题。
最佳实践相关问题:
- 在
Zone
结构的析构函数中,如果我使用 delete
,它会导致和
当我 运行 代码时出现异常。我显然做错了什么。
- 在
Zone
结构中,我可以将 name
成员设为 std::unique_ptr
吗?如果
又怎样?我尝试了很多方法,但我无法得到它
编译或工作。
- 是否有更好的方法来实现
Zone
构造函数?
代码
我在代码中添加了注释来解释该方法的意图以及我需要帮助的地方。
#include "stdafx.h"
#include <iostream>
#include <assert.h>
#include <memory>
#include <vector>
using namespace std;
struct Zone {
Zone() {}
Zone(const char* name, const float temperature, const float humidity)
{
auto bufferSize = snprintf(NULL, 0, "%s", name);
this->name = new char[bufferSize + 1];
strcpy(this->name, name);
this->temperature = temperature;
this->humidity = humidity;
}
~Zone() {
// deleting name here causes an Exception
//delete [] name;
}
char* name = nullptr;
float temperature = 0.0f;
float humidity = 0.0f;
};
class AvailableZones {
public:
AvailableZones::AvailableZones() {
m_zoneVec = std::vector<Zone>();
}
~AvailableZones() {
}
/*
Using Arguments, add a Zone to the private zoneVec member is it does not exist
If is does exist (names of zones are unique and used as the "key"), then update
the temperature and humidity of the existing zone with those in the arguments
*/
void AvailableZones::upsertZone(const char *name, const float temperature, const float humidity) {
for (auto zone : m_zoneVec) {
if (strcmp(zone.name, name) == 0) {
zone.temperature = temperature;
zone.humidity = humidity;
return;
}
}
m_zoneVec.push_back(Zone(name, temperature, humidity));
}
/*
Given a Zone name, find the zone and return it
If a Zone with the given name does not exist
return a nullptr
*/
const Zone *AvailableZones::findZone(const char *name) const {
for (auto zone : m_zoneVec) {
if (strcmp(zone.name, name) == 0) {
// I know this is not correct.
// How would I do this, without using "new" and thus
// forcing the caller to be responsible for deleting?
return &zone;
}
}
return nullptr;
}
private:
std::vector<Zone> m_zoneVec;
};
int main()
{
auto livingRoom = "Living Room";
AvailableZones availableZones;
availableZones.upsertZone("Master Bedroom", 72.0f, 50.0f);
availableZones.upsertZone(livingRoom, 70.0f, 48.0f);
availableZones.upsertZone("Study", 68.0f, 46.0f);
auto foundZone = availableZones.findZone(livingRoom);
cout << foundZone->name << endl;
cout << foundZone->temperature << endl;
cout << foundZone->humidity << endl;
assert(strcmp(livingRoom, foundZone->name) == 0);
assert(70.0f == foundZone->temperature);
assert(48.0f == foundZone->humidity);
availableZones.upsertZone(livingRoom, 74.0f, 52.0f);
foundZone = availableZones.findZone(livingRoom);
assert(strcmp(livingRoom, foundZone->name) == 0);
assert(74.0f == foundZone->temperature);
assert(52.0f == foundZone->humidity);
return 0;
}
编辑:
下面的代码实现了@max66 以及@Vaughn Cato 和@Artemy Vysotsky 提出的建议。此代码现在按照我的要求工作。进行了以下更改:
- 基于范围的 for 循环正在使用引用(或 const 引用作为
情况可能是)。默认情况下,基于范围的循环通过以下方式提供元素
值(@Vaughn Cato 也提出了这个建议)
- 在
upsertZone
方法中,我使用 emplace_back()
以便在容器提供的位置就地创建 Zone 实例。使用 push_back()
(较早的代码)创建了一个临时副本,只是被丢弃了(我假设是因为我没有实现移动构造函数)。
- 使用 strlen(如@ArtemyVysotsky 所建议的那样)而不是 snprintf,允许我在
Zone
构造函数中使用初始化列表。
- 实现了复制赋值运算符
Zone &operator=(Zone &other)
- 实现了拷贝构造函数
- 实现了移动赋值运算符
Zone &operator=(Zone &&other)
- 已实现 Move 构造函数
调查结果:
每次我向向量添加一个元素。之前的元素 "copied" 到新的容器位置,之前的元素被破坏。我希望它们会被移动而不是被复制。我不确定我是否需要做些什么来确保它们被移动而不是被复制。
进一步更新
看起来,为了使用 Move 构造函数,它需要 noexcept
。一旦我这样做,没有任何更改的相同代码现在使用移动而不是复制。
根据建议的工作代码
struct Zone {
Zone() {}
Zone(const char* name, const float zoneTemperature, const float zoneHumidity)
:name(strcpy(new char[strlen(name) + 1], name))
,temperature{ zoneTemperature }
,humidity {zoneHumidity}
{
cout << "Zone constructor: " << name << endl;
}
/* Copy Constructor */
Zone(Zone const& other)
:name(strcpy(new char[strlen(other.name) + 1], other.name))
,temperature{ other.temperature }
,humidity{ other.humidity }
{
std::cout << "In Zone Copy Constructor. name = " << other.name << ". Copying resource." << std::endl;
}
/* Move Constructor */
Zone(Zone&& other) noexcept
: name(nullptr)
, temperature(0.0f)
, humidity(0.0f)
{
std::cout << "In Zone Move Constructor. name = " << other.name << ". Moving resource." << std::endl;
// Copy the data pointer and its length from the
// source object.
name = other.name;
temperature = other.temperature;
humidity = other.humidity;
// Release the data pointer from the source object so that
// the destructor does not free the memory multiple times.
other.name = nullptr;
other.temperature = 0.0f;
other.humidity = 0.0f;
}
~Zone()
{
cout << "Zone Destructor: " << name << endl;
delete[] name;
}
/* Copy Assignment Operator */
Zone& operator=(Zone const& other) {
std::cout << "In Zone Copy Assignment Operator. name = " << other.name << "." << std::endl;
Zone tmpZone(other);
std::swap(name, tmpZone.name);
std::swap(temperature, tmpZone.temperature);
std::swap(humidity, tmpZone.humidity);
return *this;
}
/* Move Assignment Operator */
Zone& operator=(Zone&& other) noexcept {
std::cout << "In Zone Move Assignment Operator. name = " << other.name << "." << std::endl;
if (this != &other)
{
// Free the existing resource.
delete[] name;
// Copy the data pointer and its length from the
// source object.
name = other.name;
temperature = other.temperature;
humidity = other.humidity;
// Release the data pointer from the source object so that
// the destructor does not free the memory multiple times.
other.name = nullptr;
other.temperature = 0.0f;
other.humidity = 0.0f;
}
return *this;
}
char* name = nullptr;
float temperature = 0.0f;
float humidity = 0.0f;
};
class AvailableZones {
public:
AvailableZones::AvailableZones() {
m_zoneVec = std::vector<Zone>();
}
~AvailableZones() {
}
/*
Using Arguments, add a Zone to the private zoneVec member is it does not exist
If is does exist (names of zones are unique and used as the "key"), then update
the temperature and humidity of the existing zone with those in the arguments
*/
void AvailableZones::upsertZone(const char *name, const float temperature, const float humidity) {
for (auto &zone : m_zoneVec) {
if (strcmp(zone.name, name) == 0) {
zone.temperature = temperature;
zone.humidity = humidity;
return;
}
}
m_zoneVec.emplace_back(name, temperature, humidity);
}
/*
Given a Zone name, find the zone and return it
If a Zone with the given name does not exist
return a nullptr
*/
const Zone *AvailableZones::findZone(const char *name) const {
for (auto const &zone : m_zoneVec) {
if (strcmp(zone.name, name) == 0) {
return &zone;
}
}
return nullptr;
}
private:
std::vector<Zone> m_zoneVec;
};
void doWork() {
static_assert(std::is_nothrow_move_constructible<Zone>::value, "Zone should be noexcept MoveConstructible");
auto livingRoom = "Living Room";
AvailableZones availableZones;
availableZones.upsertZone("Master Bedroom", 72.0f, 50.0f);
availableZones.upsertZone(livingRoom, 70.0f, 48.0f);
availableZones.upsertZone("Study", 68.0f, 46.0f);
auto foundZone = availableZones.findZone(livingRoom);
cout << foundZone->name << endl;
cout << foundZone->temperature << endl;
cout << foundZone->humidity << endl;
assert(strcmp(livingRoom, foundZone->name) == 0);
assert(70.0f == foundZone->temperature);
assert(48.0f == foundZone->humidity);
availableZones.upsertZone(livingRoom, 74.0f, 52.0f);
foundZone = availableZones.findZone(livingRoom);
assert(strcmp(livingRoom, foundZone->name) == 0);
assert(74.0f == foundZone->temperature);
assert(52.0f == foundZone->humidity);
foundZone = availableZones.findZone("Non Existent Zone");
assert(foundZone == nullptr);
}
int main()
{
doWork();
return 0;
}
如果您不检查指针 returned 是否为 nullptr
或不
auto foundZone = availableZones.findZone(livingRoom);
cout << foundZone->name << endl;
findZone()
有很多不同的方法可以解决您的问题;为避免出现问题,我建议避免使用指针和 return 元素的副本(但您必须编写复制构造函数);但是,如果你真的想要return一个指针,你可以重写函数如下
Zone const * findZone(const char *name) const {
for ( auto const & zone : m_zoneVec) {
if (strcmp(zone.name, name) == 0) {
return & zone;
}
}
return nullptr;
}
重点是使用const
(因为方法是const
)引用到m_zoneVec
中的元素(auto const & zone : m_zoneVec
; 观察 &
) 当你现在使用 temporary copy (auto zone : m_zoneVec
; no &
所以复制而不是参考)。所以你可以return vector 的元素的指针而不是立即销毁的临时对象的指针。
您在 upsertZone()
中遇到完全相同的问题:您循环测试并(以防万一)修改 vector
中元素的 copy
for (auto zone : m_zoneVec) { // DANGER: zone is a **copy**
if (strcmp(zone.name, name) == 0) {
zone.temperature = temperature;
zone.humidity = humidity;
return;
}
}
所以你修改了立即销毁的副本;原始的 Zone
未被改动。
您必须修改 引用
for (auto & zone : m_zoneVec) { // with & zone is a **reference**
if (strcmp(zone.name, name) == 0) {
zone.temperature = temperature;
zone.humidity = humidity;
return;
}
}
但是,非常非常重要的是,您应该创建一个复制构造函数(也许还有一个移动构造函数);一个复制构造函数,它为名称分配(使用 new
)一个新数组;否则有复制指针的默认复制构造函数。
所以,举个例子,当你写
m_zoneVec.push_back(Zone(name, temperature, humidity));
你创建了一个临时对象,你通过创建副本和销毁临时对象将它推送到向量中。如果delete
,在Zone
析构函数中启用,析构临时delete
,name
并且vector中的值是使用name
那个点到自由区。从这一点来看,程序的行为是未定义的,无论如何,当 availableZone
被销毁时(在程序结束时), delete
被调用之前被删除的指针 -->崩溃!
您可以使用 emplace_back()
避免插入副本(我建议这样做)
m_zoneVec.emplace_back(name, temperature, humidity);
但在 m_zoneVec
中添加更多元素可能会导致向量重定位,因此移动副本并销毁。
如果你会用std::unique_ptr
,我想你也可以用std::shared_ptr
。
显式复制和移动构造函数创建的一个可能替代方法是使用 name
插入智能指针(根据 AvailableZones
.[=43 的使用,唯一或共享=]
我已经在其他地方和此处搜索过执行此操作的方法,但没有找到任何解决我的问题和疑虑的答案。
约束条件:
- 我在 嵌入式 设备上使用 C++ 11。
- 我不会用
std::string
- 我不能用
std::make_unique()
(但我可以用std::unique_ptr
和new
) - 我不会用
strcpy_s()
我遇到的问题
我遇到的主要问题是,在 AvailableZones::upsertZone
方法中,我想向矢量添加一个区域(如果它尚不存在)(使用名称参数作为 "key").如果存在,我想更新该区域的温度和湿度成员。 "adding" 部分有效,但是更新部分无效。
我的下一期是 AvailableZones::findZone
会员。我希望能够 return 一个区域,以便调用者不对 freeing/deleting returned 值负责。
顾虑:
作为 C++ 的新手,我很确定我没有以正确的 C++11 方式做很多事情。我对 any/all 指导持开放态度(实际上是渴望)。
在 AvailableZones::findZone
方法中,我想要 return Zone
而不是创建副本或使用 new
/malloc
。看来我需要使用常规 for
/while
循环?我看过一些迭代器代码,但它看起来很像 confusing/complicated 但我不确定使用迭代器是否也能解决这个问题。
最佳实践相关问题:
- 在
Zone
结构的析构函数中,如果我使用delete
,它会导致和 当我 运行 代码时出现异常。我显然做错了什么。 - 在
Zone
结构中,我可以将name
成员设为std::unique_ptr
吗?如果 又怎样?我尝试了很多方法,但我无法得到它 编译或工作。 - 是否有更好的方法来实现
Zone
构造函数?
代码
我在代码中添加了注释来解释该方法的意图以及我需要帮助的地方。
#include "stdafx.h"
#include <iostream>
#include <assert.h>
#include <memory>
#include <vector>
using namespace std;
struct Zone {
Zone() {}
Zone(const char* name, const float temperature, const float humidity)
{
auto bufferSize = snprintf(NULL, 0, "%s", name);
this->name = new char[bufferSize + 1];
strcpy(this->name, name);
this->temperature = temperature;
this->humidity = humidity;
}
~Zone() {
// deleting name here causes an Exception
//delete [] name;
}
char* name = nullptr;
float temperature = 0.0f;
float humidity = 0.0f;
};
class AvailableZones {
public:
AvailableZones::AvailableZones() {
m_zoneVec = std::vector<Zone>();
}
~AvailableZones() {
}
/*
Using Arguments, add a Zone to the private zoneVec member is it does not exist
If is does exist (names of zones are unique and used as the "key"), then update
the temperature and humidity of the existing zone with those in the arguments
*/
void AvailableZones::upsertZone(const char *name, const float temperature, const float humidity) {
for (auto zone : m_zoneVec) {
if (strcmp(zone.name, name) == 0) {
zone.temperature = temperature;
zone.humidity = humidity;
return;
}
}
m_zoneVec.push_back(Zone(name, temperature, humidity));
}
/*
Given a Zone name, find the zone and return it
If a Zone with the given name does not exist
return a nullptr
*/
const Zone *AvailableZones::findZone(const char *name) const {
for (auto zone : m_zoneVec) {
if (strcmp(zone.name, name) == 0) {
// I know this is not correct.
// How would I do this, without using "new" and thus
// forcing the caller to be responsible for deleting?
return &zone;
}
}
return nullptr;
}
private:
std::vector<Zone> m_zoneVec;
};
int main()
{
auto livingRoom = "Living Room";
AvailableZones availableZones;
availableZones.upsertZone("Master Bedroom", 72.0f, 50.0f);
availableZones.upsertZone(livingRoom, 70.0f, 48.0f);
availableZones.upsertZone("Study", 68.0f, 46.0f);
auto foundZone = availableZones.findZone(livingRoom);
cout << foundZone->name << endl;
cout << foundZone->temperature << endl;
cout << foundZone->humidity << endl;
assert(strcmp(livingRoom, foundZone->name) == 0);
assert(70.0f == foundZone->temperature);
assert(48.0f == foundZone->humidity);
availableZones.upsertZone(livingRoom, 74.0f, 52.0f);
foundZone = availableZones.findZone(livingRoom);
assert(strcmp(livingRoom, foundZone->name) == 0);
assert(74.0f == foundZone->temperature);
assert(52.0f == foundZone->humidity);
return 0;
}
编辑: 下面的代码实现了@max66 以及@Vaughn Cato 和@Artemy Vysotsky 提出的建议。此代码现在按照我的要求工作。进行了以下更改:
- 基于范围的 for 循环正在使用引用(或 const 引用作为 情况可能是)。默认情况下,基于范围的循环通过以下方式提供元素 值(@Vaughn Cato 也提出了这个建议)
- 在
upsertZone
方法中,我使用emplace_back()
以便在容器提供的位置就地创建 Zone 实例。使用push_back()
(较早的代码)创建了一个临时副本,只是被丢弃了(我假设是因为我没有实现移动构造函数)。 - 使用 strlen(如@ArtemyVysotsky 所建议的那样)而不是 snprintf,允许我在
Zone
构造函数中使用初始化列表。 - 实现了复制赋值运算符
Zone &operator=(Zone &other)
- 实现了拷贝构造函数
- 实现了移动赋值运算符
Zone &operator=(Zone &&other)
- 已实现 Move 构造函数
调查结果: 每次我向向量添加一个元素。之前的元素 "copied" 到新的容器位置,之前的元素被破坏。我希望它们会被移动而不是被复制。我不确定我是否需要做些什么来确保它们被移动而不是被复制。
进一步更新
看起来,为了使用 Move 构造函数,它需要 noexcept
。一旦我这样做,没有任何更改的相同代码现在使用移动而不是复制。
根据建议的工作代码
struct Zone {
Zone() {}
Zone(const char* name, const float zoneTemperature, const float zoneHumidity)
:name(strcpy(new char[strlen(name) + 1], name))
,temperature{ zoneTemperature }
,humidity {zoneHumidity}
{
cout << "Zone constructor: " << name << endl;
}
/* Copy Constructor */
Zone(Zone const& other)
:name(strcpy(new char[strlen(other.name) + 1], other.name))
,temperature{ other.temperature }
,humidity{ other.humidity }
{
std::cout << "In Zone Copy Constructor. name = " << other.name << ". Copying resource." << std::endl;
}
/* Move Constructor */
Zone(Zone&& other) noexcept
: name(nullptr)
, temperature(0.0f)
, humidity(0.0f)
{
std::cout << "In Zone Move Constructor. name = " << other.name << ". Moving resource." << std::endl;
// Copy the data pointer and its length from the
// source object.
name = other.name;
temperature = other.temperature;
humidity = other.humidity;
// Release the data pointer from the source object so that
// the destructor does not free the memory multiple times.
other.name = nullptr;
other.temperature = 0.0f;
other.humidity = 0.0f;
}
~Zone()
{
cout << "Zone Destructor: " << name << endl;
delete[] name;
}
/* Copy Assignment Operator */
Zone& operator=(Zone const& other) {
std::cout << "In Zone Copy Assignment Operator. name = " << other.name << "." << std::endl;
Zone tmpZone(other);
std::swap(name, tmpZone.name);
std::swap(temperature, tmpZone.temperature);
std::swap(humidity, tmpZone.humidity);
return *this;
}
/* Move Assignment Operator */
Zone& operator=(Zone&& other) noexcept {
std::cout << "In Zone Move Assignment Operator. name = " << other.name << "." << std::endl;
if (this != &other)
{
// Free the existing resource.
delete[] name;
// Copy the data pointer and its length from the
// source object.
name = other.name;
temperature = other.temperature;
humidity = other.humidity;
// Release the data pointer from the source object so that
// the destructor does not free the memory multiple times.
other.name = nullptr;
other.temperature = 0.0f;
other.humidity = 0.0f;
}
return *this;
}
char* name = nullptr;
float temperature = 0.0f;
float humidity = 0.0f;
};
class AvailableZones {
public:
AvailableZones::AvailableZones() {
m_zoneVec = std::vector<Zone>();
}
~AvailableZones() {
}
/*
Using Arguments, add a Zone to the private zoneVec member is it does not exist
If is does exist (names of zones are unique and used as the "key"), then update
the temperature and humidity of the existing zone with those in the arguments
*/
void AvailableZones::upsertZone(const char *name, const float temperature, const float humidity) {
for (auto &zone : m_zoneVec) {
if (strcmp(zone.name, name) == 0) {
zone.temperature = temperature;
zone.humidity = humidity;
return;
}
}
m_zoneVec.emplace_back(name, temperature, humidity);
}
/*
Given a Zone name, find the zone and return it
If a Zone with the given name does not exist
return a nullptr
*/
const Zone *AvailableZones::findZone(const char *name) const {
for (auto const &zone : m_zoneVec) {
if (strcmp(zone.name, name) == 0) {
return &zone;
}
}
return nullptr;
}
private:
std::vector<Zone> m_zoneVec;
};
void doWork() {
static_assert(std::is_nothrow_move_constructible<Zone>::value, "Zone should be noexcept MoveConstructible");
auto livingRoom = "Living Room";
AvailableZones availableZones;
availableZones.upsertZone("Master Bedroom", 72.0f, 50.0f);
availableZones.upsertZone(livingRoom, 70.0f, 48.0f);
availableZones.upsertZone("Study", 68.0f, 46.0f);
auto foundZone = availableZones.findZone(livingRoom);
cout << foundZone->name << endl;
cout << foundZone->temperature << endl;
cout << foundZone->humidity << endl;
assert(strcmp(livingRoom, foundZone->name) == 0);
assert(70.0f == foundZone->temperature);
assert(48.0f == foundZone->humidity);
availableZones.upsertZone(livingRoom, 74.0f, 52.0f);
foundZone = availableZones.findZone(livingRoom);
assert(strcmp(livingRoom, foundZone->name) == 0);
assert(74.0f == foundZone->temperature);
assert(52.0f == foundZone->humidity);
foundZone = availableZones.findZone("Non Existent Zone");
assert(foundZone == nullptr);
}
int main()
{
doWork();
return 0;
}
如果您不检查指针 returned 是否为 nullptr
或不
auto foundZone = availableZones.findZone(livingRoom);
cout << foundZone->name << endl;
findZone()
有很多不同的方法可以解决您的问题;为避免出现问题,我建议避免使用指针和 return 元素的副本(但您必须编写复制构造函数);但是,如果你真的想要return一个指针,你可以重写函数如下
Zone const * findZone(const char *name) const {
for ( auto const & zone : m_zoneVec) {
if (strcmp(zone.name, name) == 0) {
return & zone;
}
}
return nullptr;
}
重点是使用const
(因为方法是const
)引用到m_zoneVec
中的元素(auto const & zone : m_zoneVec
; 观察 &
) 当你现在使用 temporary copy (auto zone : m_zoneVec
; no &
所以复制而不是参考)。所以你可以return vector 的元素的指针而不是立即销毁的临时对象的指针。
您在 upsertZone()
中遇到完全相同的问题:您循环测试并(以防万一)修改 vector
for (auto zone : m_zoneVec) { // DANGER: zone is a **copy**
if (strcmp(zone.name, name) == 0) {
zone.temperature = temperature;
zone.humidity = humidity;
return;
}
}
所以你修改了立即销毁的副本;原始的 Zone
未被改动。
您必须修改 引用
for (auto & zone : m_zoneVec) { // with & zone is a **reference**
if (strcmp(zone.name, name) == 0) {
zone.temperature = temperature;
zone.humidity = humidity;
return;
}
}
但是,非常非常重要的是,您应该创建一个复制构造函数(也许还有一个移动构造函数);一个复制构造函数,它为名称分配(使用 new
)一个新数组;否则有复制指针的默认复制构造函数。
所以,举个例子,当你写
m_zoneVec.push_back(Zone(name, temperature, humidity));
你创建了一个临时对象,你通过创建副本和销毁临时对象将它推送到向量中。如果delete
,在Zone
析构函数中启用,析构临时delete
,name
并且vector中的值是使用name
那个点到自由区。从这一点来看,程序的行为是未定义的,无论如何,当 availableZone
被销毁时(在程序结束时), delete
被调用之前被删除的指针 -->崩溃!
您可以使用 emplace_back()
避免插入副本(我建议这样做)
m_zoneVec.emplace_back(name, temperature, humidity);
但在 m_zoneVec
中添加更多元素可能会导致向量重定位,因此移动副本并销毁。
如果你会用std::unique_ptr
,我想你也可以用std::shared_ptr
。
显式复制和移动构造函数创建的一个可能替代方法是使用 name
插入智能指针(根据 AvailableZones
.[=43 的使用,唯一或共享=]