可以为每个内置数据类型使用一个构造函数 C++

Is ok to have one constructor for each built in data types C++

假设我们要创建一个class,其构造函数或构造函数将在变量words中保存一个很长的数字:

class myClass {
    private:
        unsigned long long int words;

    public:
        ...
}

但我希望能够使用任何内置类型初始化 class,例如:

int a; myClass A(a);
float b; myClass B(b);
long long int c; myClass C(c);

我是否应该为每个类型(列出 here)实现一个构造函数,形式如下:

...
public:
    ...
    myClass(const short int i): 
        words(i) {}

    myClass(const unsigned short int i);
        words(i) {}

    etc...

或者我应该只实现 unsigned long long int:

的构造函数
...
public:
    ...
    myClass(const unsigned long long int i): 
        words(i) {}

    ...

据我了解,使用第一个选项(每个选项一个),会发生这种情况:

int a; myClass(a);
// Call constructor myClass(const int i)
// Convert the value i to unsigned long long int and initialize words with it

第二个选项(一劳永逸):

int a; myClass(a);
// Convert i to unsigned long long int and this new value as a parameter for the constructor
// Initialize words with it

现在,我应该使用哪一个?。我猜对 unsigned long long int 使用一个构造函数会更好。

是否有任何情况下每个都有一个构造函数更好?

我建议为 unsigned long long 实现一个构造函数。

原因是: 执行下面的代码。由于歧义,代码将无法编译。

然后删除 int 构造函数并重新构建。现在代码将编译并成功执行。

#include <iostream>

class myClass {
    private:
        unsigned long long int words;

    public:

    myClass(int i)
    {
        std::cout<<"in Int constructor"<<std::endl;

    }

    myClass(long long int i)
    {

        std::cout<<"in long constructor"<<std::endl;
    }

};

int main()
{
    myClass m(10000000000);    

    return 0;   
}

您应该创建多个构造函数的唯一原因是需要额外的处理或转换逻辑。例如:

#include <string>
#include <iostream>

class myClass
{

public:
    unsigned long long int words;// public for ease of example

    // will consume anything convertable to unsigned long long
    myClass(unsigned long long int val) :
            words(val)
    {
    }

    // will consume anything convertable to std::string, and then convert 
    // the string to unsigned long long
    myClass(std::string val) :
            words(std::stoull(val))
    {
    }

};

int main()
{
    std::cout << myClass{ 10 }.words << ": 10" << std::endl;
    std::cout << myClass{ -10 }.words << ": -10 (Two's compliment wrap)" << std::endl;
    std::cout << myClass{ 3.14 }.words << ": 3.14 (Truncated)" << std::endl;
    std::cout << myClass{ "10" }.words << ": \"10\"" << std::endl;
    std::cout << myClass{ "-10" }.words << ": \"-10\" (Two's compliment wrap)" << std::endl;
}

10 很容易转换。 -10 和 3.14 被转换,但会产生警告,因为值会被转换损坏。 “10”和“-10”将被 string 参数化的构造函数接受,但“-10”将被 std::stoull 破坏。如果需要,将需要额外的逻辑,并可能使用 strtoull 来处理此问题。