【发布时间】:2019-03-27 01:31:22
【问题描述】:
我想创建一个“Act”对象向量,其中包含指向“Eat”或“Drink”动态分配对象的指针。新对象的放置方式如下:
action_vector.emplace_back(Act::BehaviorType::eat);
但是,这是段错误,我不知道为什么。我认为 emplace_back 会隐式调用移动构造函数,而不是析构函数,但出于某种原因,它是(我认为)是什么搞砸了一切。
有什么方法可以成功创建此类对象的向量?
以下是其余代码及其输出。对不起,如果它有点冗长,但基本上它只是一个策略模式。
#include <iostream>
#include <vector>
class IBehavior
{
public:
IBehavior() = default;
virtual ~IBehavior() = default;
virtual void execute() = 0;
};
class Drink : public IBehavior
{
public:
Drink(): IBehavior() {}
~Drink() {}
void execute() { std::cout << "Drinking" << std::endl; }
};
class Eat : public IBehavior
{
public:
Eat(): IBehavior() {}
~Eat() {}
void execute() { std::cout << "Eating" << std::endl; }
};
class Act
{
IBehavior * b;
public:
enum class BehaviorType { eat = 0, drink = 1 };
Act() = default;
~Act()
{
std::cout << "Calling the destructor" << std::endl;
delete b;
}
Act(BehaviorType b_type) { SetBehavior(b_type); }
Act(Act&& act)
{
std::cout << "Calling the move constructor" << std::endl;
this->b = act.b;
}
void SetBehavior(BehaviorType b_type)
{
if(b_type == BehaviorType::eat) b = new Eat();
if(b_type == BehaviorType::drink) b = new Drink();
}
void execute() { b->execute(); }
};
int main(int argc, char * argv[])
{
std::vector<Act> action_vector;
for(int i = 0; i < 10; ++i)
{
action_vector.emplace_back(Act::BehaviorType::eat);
action_vector[i].execute();
}
return 0;
}
输出:
Eating
Calling the move constructor
Calling the destructor
Eating
Calling the move constructor
Calling the move constructor
Calling the destructor
Calling the destructor
Segmentation fault: 11
【问题讨论】:
-
当移动构造函数或移动赋值“窃取”一次性资源时,它不能将其留在原始对象中以供析构函数获取。所以在这种情况下,将指针
b复制到this(this->b = act.b)后,应该设置act.b = nullptr。
标签: c++ pointers vector strategy-pattern