Можно использовать один конструктор для каждого встроенного типа данных. Переполнение стека

Допустим, мы собираемся создать класс, конструктор или конструкторы которого будут сохранены в переменной words очень длинный номер:

class myClass {
private:
unsigned long long int words;

public:
...
}

Но я хочу иметь возможность инициализировать класс, используя любой встроенный тип, например:

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

Должен ли я реализовать конструктор для каждого из типов (в списке Вот) в виде:

...
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,

Есть ли сценарий, где лучше иметь конструктор для каждого?

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, будет необходимо обработать это, если требуется.

0

Другие решения

Я предложу реализовать один конструктор для unsigned long long it.

Причина в том, что:
выполнить код ниже. Код не будет компилироваться из-за неоднозначности.

Затем удалите конструктор 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;
}
0

По вопросам рекламы [email protected]