如何检查在C++中使用了哪个构造函数

How to check which constructor is used in C++

本文关键字:构造函数 C++ 何检查 检查      更新时间:2023-10-16

我修改了这里的问题。现在它看起来很像一个答案,:)。谢谢大家解决这个问题。

我的类中有一些重载构造函数,比如这个

#include <string>
#ifdef EXPLICIT_ENUM_CONVERSION
enum struct E
#else
enum E
#endif
{
A,
B
};
class A
{
public:
A(unsigned int i){};
A(std::string const& s){};
};

以及一个函数声明,它实际上接受a作为参数

void func(const class A& a)
{
}

但是调用者通过传递一个enum来调用它。

int main()    
{
#ifdef EXPLICIT_ENUM_CONVERSION
E e=E::A;
func((unsigned int)e);  
#else
E e=A;
func(e);  
#endif
}

问题:通过注释掉A(unsigned)并再次编译以获得错误,我可以判断所使用的构造函数。但是,有没有更好的方法来判断如何从gcc命令行或objdump转换类型?

答:如果使用-O0进行编译,然后使用objdump-CSr,则使用的类构造函数将显示在obgdump中。

问题:有什么方法可以防止用gcc自动转换enumunsigned

答案:看我选的答案。作用域枚举是在C++11中引入的,可以满足这个目的。您可以在EXPLICIT_ENUM_CONVERSION中检查代码。

根据您的目标,这里有3条建议:

如果您想更好地理解转换规则

  1. 阅读《加速C++》一书中的相关部分(首选,转换步骤)
  2. 阅读《更有效的C++》一书中的相关部分(不超过1个隐式转换)
  3. 阅读C++标准,例如C++14草案

如果您想找到一些错误

  • 使用printf调试或登录您的ctor
  • 或使用调试器
  • 或者将代码分解为更小的步骤,例如

    E e;       
    auto i = static_cast<u32>(e);
    func(i);
    

    static_cast<u32>(e)使用显式类型初始化程序习惯用法(请参阅有效的现代C++项目6)

如果你想避免错误,你应该避免过于复杂的隐式转换,并警惕用户定义的转换函数(更有效的C++项目5)。例如:

  • 显式转换ctor:explicit A(u32 i){};
  • 作用域枚举:enum class E{...}
  • 作用域枚举作为ctor参数:A(E enumElement){};