有没有一种很好的方法来捕捉或避免这种微妙的错误?

时间:2018-01-05 19:20:57

标签: c++

我的c ++很生疏,所以在尝试改进一些代码时,我几天前通过更改一些来自MyClass *const thingMyclass& thing的调用来编写,我注意到没有任何关于代码的抱怨人为的例子。

#include <iostream>

class Foo {
    public:
        Foo() {
            std::cout << "foo created" << std::endl;
        }
        ~Foo() {
            std::cout << "foo destroyed" << std::endl;
        }
        Foo(Foo& other) {
           member = other.member;
           std::cout << "foo copied" << std::endl;
        }
        bool member = false;
};

class Bar {
    public:
        Bar(Foo& foo) :foo_(foo) { } 
    Foo foo_;  // **** HERE IS THE BUG this should be: Foo& foo_;
};

int main() {
    Foo foo;
    Bar barOne(foo);
    Bar barTwo(foo);
    foo.member = true;
    std::cout << barOne.foo_.member << std::endl;
    std::cout << barTwo.foo_.member << std::endl;
}

我真的想拥有一个Foo对象,但是因为我忘记了&我得到了三个。

foo created
foo copied
foo copied
0
0
foo destroyed
foo destroyed
foo destroyed

添加&我得到了正确的结果。

foo created
1
1
foo destroyed

注意:Foo,构造函数和析构函数就是为了演示正在发生的事情。

我知道这是合法的,但如果你将一个Object声明为成员变量,是否会有一个编译器标志警告你?在成员变量中存储引用是不好的做法?我不会想到它,但就像我说我的c ++至少可以说是生锈的。

更新

回答我重构的问题。我正在做类似的事情。我正在重构引用,因为我读到的有关现代c ++的所有内容都表示更喜欢引用而不是指针。

class Bar {
    public:
        Bar(Foo const* foo) :foo_(foo) { } 
    Foo const* foo_;
};

int main() {
    Foo foo;
    Bar barOne(&foo);
    Bar barTwo(&foo);
    foo.member = true;
    std::cout << barOne.foo_->member << std::endl;
    std::cout << barTwo.foo_->member << std::endl;
}

2 个答案:

答案 0 :(得分:2)

  

我知道这是合法的,但是如果你将一个Object声明为一个成员变量,是否会有一个编译器标志警告你?

我怀疑是否有这样的旗帜。一种类型的对象被存储为其他类型的成员变量太多次,并且该标志的位置太多而无用。

  

在成员变量中存储引用是不是一种坏习惯吗?

不,不是。但是,你必须知道你遇到问题的地方。

只要持有引用的对象的生命在它所持有的对象的生命周期结束之前结束,你就可以了。否则,你最终会坚持悬挂参考。使用悬空引用是造成未定义行为的原因。

答案 1 :(得分:0)

将对象存储为其他对象的成员完全没问题。 如果您确定持有引用的对象永远不会超过引用的变量,那么将引用存储为成员是可以的。

相关问题