È un buon progetto richiedere agli utenti della classe di utilizzare il riferimento Rvalue?

2

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();
}
    
posta authchir 03.12.2011 - 16:39
fonte

1 risposta

3

No, questo è un comportamento non definito. La variabile temporanea non avrà una durata estesa.

Inoltre, direi che è un odore di codice non offrire Derived1 e Derived2. L'accesso solo attraverso la classe base è qualcosa che si fa solo se la classe derivata non può essere conosciuta in fase di compilazione.

    
risposta data 03.12.2011 - 17:06
fonte

Leggi altre domande sui tag