c++ constructor idioms optional-parameters

c++ - Evitando el tedio de los parámetros opcionales.



constructor idioms (4)

Si tengo un constructor con, por ejemplo, 2 parámetros requeridos y 4 parámetros opcionales, ¿cómo puedo evitar escribir 16 constructores o incluso los 10 o más constructores que tendría que escribir si usara parámetros predeterminados (lo cual no me gusta porque es pobre)? auto-documentación)? ¿Hay modismos o métodos que utilicen plantillas que pueda usar para hacerlo menos tedioso? (¿Y más fácil de mantener?)


¿Qué pasa si hiciste un objeto de parámetro que contenía todos los campos? Luego, simplemente puede pasar eso y establecer los campos que necesite. Probablemente haya un nombre para ese patrón, aunque no estoy seguro de lo que es ...

ACTUALIZAR:

El código podría parecerse a esto:

paramObj.x=1; paramObj.y=2; paramObj.z=3; paramObj.magic=true; ... //set many other "parameters here" someObject myObject = new someObject(paramObj);

y dentro del constructor someObject puede establecer valores predeterminados para cosas que aún no se han establecido (o generar un error si fuera obligatorio).

Honestamente, no soy un gran fanático de esta solución, pero la he usado una o dos veces cuando paramObj tenía sentido al contener un conjunto de datos que generalmente iban todos juntos (por lo que podríamos usarlo para más que solo constructores), Y era mejor que múltiples constructores. Encontré que era feo pero funcionó, YMMV.


Es posible que esté interesado en el idioma del parámetro nombrado .

Para resumir, cree una clase que contenga los valores que desea pasar a su (s) constructor (es). Agregue un método para establecer cada uno de esos valores y haga que cada método return *this; al final. Tenga un constructor en su clase que tome una referencia constante a esta nueva clase. Esto puede ser usado como tal:

class Person; class PersonOptions { friend class Person; string name_; int age_; char gender_; public: PersonOptions() : age_(0), gender_(''U'') {} PersonOptions& name(const string& n) { name_ = n; return *this; } PersonOptions& age(int a) { age_ = a; return *this; } PersonOptions& gender(char g) { gender_ = g; return *this; } }; class Person { string name_; int age_; char gender_; public: Person(const PersonOptions& opts) : name_(opts.name_), age_(opts.age_), gender_(opts.gender_) {} }; Person p = PersonOptions().name("George").age(57).gender(''M'');


Todo nuevo para C ++ 17

#include <optional> using optional_int = std::optional<int>; class foo { int arg0, arg1; // required int arg2, arg3; // optional const int default_2 = -2; const int default_3 = -3; public: foo(int arg0, int arg1, optional_int opt0 = {}, optional_int opt1 = {}) : arg0(arg0), arg1(arg1) , arg2(opt0.value_or(default_2)) , arg3(opt1.value_or(default_3)) { } }; int main() { foo bar(42, 43, {}, 45); // Take default for opt0 (arg2) return 0; }

Tengo una implementación de spline cúbica que le permite al usuario, opcionalmente, especificar la primera derivada en el extremo izquierdo, el extremo derecho o ambos. Si no se especifica una derivada, entonces el código en efecto calcula una, suponiendo que la segunda derivada es cero (la llamada "spline natural"). Aquí hay un fragmento para el extremo izquierdo.

// Calculate the second derivative at the left end point if (!left_deriv.has_value()) { ddy[0]=u[0]=0.0; // "Natural spline" } else { const real yP0 = left_deriv.value(); ddy[0] = -0.5; u[0]=(3.0/(x[1]-x[0]))*((y[1]-y[0])/(x[1]-x[0])-yP0); }