我有以下内容:
enum class color_t {BLEU, RED};
class Evaluator{
Foo my_foo;
int initalise(){
color_t* ptr_my_color = NULL;
color_t my_color = color_t::BLEU;
ptr_my_color = &my_color;
my_foo = new Foo(ptr_my_color);
}
int run(){my_foo.run();}
}
class Foo{
color_t* ptr_my_color;
public:
Dist(color_t* ptr_my_color = NULL) {
this->ptr_my_color = ptr_my_color;
}
int run(){
if(ptr_my_color!=NULL){
if((*ptr_my_color)==color_t::BLEU){
cerr << "1st if" << endl;
} else {
cerr << "1st else" << endl;
}
}
//do some stuff
if(ptr_my_color!=NULL){
if((*ptr_my_color)==color_t::BLEU){
cerr << "2nd if" << endl;
} else {
cerr << "2nd else" << endl;
}
}
}
}
int main(int argc, char** argv) {
Evaluator my_eval();
my_eval.initalise();
my_eval.run();
}
打印出来:
1st if
2nd else
为什么会这样?我的猜测:非指针枚举color_t my_color
在堆栈上创建,当initialise()
完成时,它被标记为“随意覆盖”。然后在第一个if
指针仍然可以找到它,但做其他东西会覆盖它然后再找不到它?但为什么它仍然通过if(ptr_my_color!=NULL){
?
我该如何解决?通过给class Foo
一个成员变量color_t my_color
并在构造函数中再次创建枚举?
答案 0 :(得分:1)
我建议将enum class
作为 const引用传递给构造函数,并包含一个INVALID
值来标记&#34; not set&#34;情况下:
#include <iostream>
using namespace std;
enum class color_t {BLEU, RED, INVALID};
class Foo{
color_t my_color;
public:
Foo(color_t const& color = color_t::INVALID) {
my_color = color;
}
void run(){
if(my_color!=color_t::INVALID){
if(my_color==color_t::BLEU){
cerr << "1st if" << endl;
} else {
cerr << "1st else" << endl;
}
}
//...
}
};
class Evaluator{
Foo* my_foo;
public:
void initalise(){
color_t my_color = color_t::BLEU;
my_foo = new Foo(my_color);
}
// ...
};
这里的关键区别实际上是将成员my_color
更改为简单类型而不是指针。这意味着在Foo
的构造函数中,在my_color = color
行,您实际上采用color
的副本并将其存储为my_color
。然后,您不必担心color
是否是对堆栈中可能被清除的内容的引用(就像在指针案例中那样)。
即使作为指针传递,您也可以通过存储为简单类型并在构造函数中获取副本来获得相同的效果:my_color = *ptr_my_color
。但是,在这种情况下,我当然更喜欢使用引用。
答案 1 :(得分:0)
它仍然通过检查,因为该指针不为null,如果你去检查它,指向内存中的某个地方也不是null。正确的方法是将其包装在s unique_ptr中,或者如果由于某种原因你想要处理原始指针,你应该释放数据并将指针设置为null,即使在这个虚拟测试中也不需要堆分配。 / p>