Таким образом, оригинальный Getter / Setter похож на следующий стиль (с добавлением дополнительных приведений, также имейте в виду, что я использую int и float в этих примерах, это могут быть более сложные данные)
struct JustAnInteger {
int i;
};
class Foo {
private:
int _bar;
public:
Foo(int bar) : _bar(bar) {}
void setBar(int bar) { _bar = bar; }
int getBar() const {
return _bar;
}
double getBarDouble() const {
return (double)_bar;
}
std::string getBarString() const {
return std::to_string(_bar);
}
JustAnInteger getBarJustAnInteger() const {
return JustAnInteger{ _bar };
}
};
Будет ли переход на следующий способ хорошей или плохой идеей?
class Foo {
private:
int _bar;
public:
Foo(int bar) : _bar(bar) {}
void bar(int bar) { _bar = bar; }
template <class T = int> //int is the original type
T bar() const;
template <>
int bar<int>() const {
return _bar;
}
template <> double bar<double>() const {
return (double)_bar;
}
template <> std::string bar<std::string>() const {
return std::to_string(_bar);
}
template <> JustAnInteger bar<JustAnInteger>() const {
return JustAnInteger{ bar() };
}
};
Этот способ позволит легко изменить тип _bar, например, на float
class Foo{
private:
float _bar;
public:
Foo(int bar) : _bar((float)bar) {}
Foo(float bar) : _bar(bar) {}
void bar(int bar) { _bar = (float)bar; }
void bar(float bar) { _bar = bar; }
template <class T = int>
T bar() const;
template <> int bar<int>() const {
return (int)_bar;
}
template <> double bar<double>() const {
return (double)_bar;
}
template <> std::string bar<std::string>() const {
return std::to_string(_bar);
}
template <> JustAnInteger bar<JustAnInteger>() const {
return JustAnInteger{ bar() };
}
};
И не должен нарушать другие части кода
Foo foo(2);
foo.bar(2.999f); //Now we can use floats!
int a = foo.bar(); //Still an int
double b = foo.bar<double>(); //can keep using it, and we gain precision