2017-03-07 20 views
1

如果B类的构造函数接受对类A的对象的引用并存储该引用,并且使用该类的临时文件调用,则该引用在构造函数完成后似乎变为无效见example run)。然而,没有任何的静态代码分析工具,我试图检测到这种情况:检测对已释放的未命名临时文件的访问

  • g++ -Wall -Wextra -pedantic
  • clang++ -Wall -Wextra -pedantic
  • cppcheck
  • clang-tidy
  • 克利翁的综合检查

我想我明白编译器的行为是否符合s到标准。如何在现有的代码库中检测这样的代码?哪些编程规范可以帮助避免这种难以捕捉的错误?

以下完整示例代码和注释输出完整性。

#include <iostream> 

class A { 
public: 
    explicit A(int i) : i_(i) { std::cerr << this << " A\n"; } 
    ~A() { std::cerr << this << " ~A\n"; } 

    void do_() const { std::cerr << this << " " << i_ << "\n"; } 

private: 
    int i_; 
}; 

class B { 
public: 
    explicit B(const A& a) : a_(a) { std::cerr << this << " B\n"; } 
    ~B() { std::cerr << this << " ~B\n"; } 
    void do_() const { std::cerr << this << " "; a_.do_(); } 

    const A& a_; 
}; 

int main(int, char**) { 
    B b(A(42)); 
    int i = 0; 
    b.do_(); 
    std::cerr << i << " main\n"; 
} 

输出:

# Construction of b 
0xffa66138 A 
0xffa66134 B 
0xffa66138 ~A 
# Calling b.do_() 
0xffa66134 0xffa66138 42 
# Printing i in main() 
0 main 
# End of main() 
0xffa66134 ~B 
+2

只需搜索包含引用作为成员变量的类 - 这几乎总是不是你想要的。正则表达式应该能够找到大多数情况。 –

+1

我只会在课堂上禁止参考成员。 – NathanOliver

+0

即使你禁止/阻止临时对象,如果一个“B”对象超过了'A'的参考对象(悬挂参考),你是否仍然有问题? – UnholySheep

回答

2

您可以临时禁止与已删除构造

class B { 
public: 
    explicit B(const A& a) : a_(a) { std::cerr << this << " B\n"; } 
    B(A&&) = delete; 
// ... 
}; 

的一种方式,以保证这项的A寿命比B不再将采取shared_ptr

相关问题