Ho la seguente situazione in cui ho una classe base e più classi derivate da polimorfismi:
#include <iostream>
class Base {
public:
virtual void foo() = 0;
};
class Derived1 : public Base {
public:
virtual void foo() { std::cout << "Derived1::foo()\n"; };
};
class Derived2 : public Base {
public:
virtual void foo() { std::cout << "Derived2::foo()\n"; };
};
Voglio assicurarmi che i miei utenti di classe sempre usino la classe base per usare l'oggetto di questa gerarchia. Mi è venuta l'idea di fornire metodi di fabbrica per restituire l'oggetto buono. Da ora, i metodi hanno questo aspetto:
Base&& make_base(int i) {
if(i == 1)
return Derived1();
else
return Derived2();
}
Il client può quindi utilizzarlo in questo modo:
int main() {
Base&& b = make_base(1);
b.foo();
}
Supponendo che la compatibilità con C ++ 03 sia non necessaria, è considerata una buona pratica?
Modifica
AS DeadMG ha sottolineato, il mio make_base iniziale ha un comportamento indefinito. Se non posso richiedere ai clienti di usare solo la classe Base, vorrei poterlo raccomandare. Questo tipo di fabbrica è un'idea migliore?
#include <type_traits>
#include <string>
template <class Derived>
Derived make_base() {
static_assert(
std::is_base_of<Base, Derived>::value,
"'Derived' must derived from 'Base'.");
// Default behaviour
return Derived();
}
template <>
Derived2 make_base<Derived2>() {
// Specialise behaviour
// Do something
return Derived2();
}
int main() {
auto b = make_base<std::string>(); // Error, 'Derived' must derived from 'Base'.
Base&& b1 = make_base<Derived1>(); // call make_base()
Base&& b2 = make_base<Derived2>(); // call make_base<Derived2>()
b1.foo();
b2.foo();
}