Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I have the following situation where I have a base class and multiple polymorphics derived classes:

#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"; };
};

I want to make sure that my class users will always use the base class to use object of this hierachy. I got the idea to provide a factory methods returning the good object. From now, the methods look like this:

Base&& make_base(int i) {
    if(i == 1)
        return Derived1();
    else
        return Derived2();
}

The client can then use it that way:

int main() {
    Base&& b = make_base(1);
    b.foo();
}

Assuming C++03 compatibility is not needed, is this considered a good practice?

PS: Sorry for my writing, I am not an english native person.

Edit

AS DeadMG point out, my initial make_base have undefined behaviour. If I can't require clients to only use Base class, I which I could recommand it. Is this kind of factory a better idea?

#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();
}
share|improve this question
1  
Generally speaking, rvalue references are an implementation detail, and class users should almost never be exposed to them. –  FredOverflow Dec 4 '11 at 10:12

1 Answer 1

up vote 3 down vote accepted

No, this is undefined behaviour. The temporary variable will not have it's lifetime extended.

In addition, I'd say it's a code smell to not offer Derived1 and Derived2. Only accessing through the base class is something you only do if the derived class cannot be known at compile-time.

share|improve this answer
    
Which part is undefined? Return a Rvalue from a function or capture a Rvalue from a return object? –  authchir Dec 3 '11 at 16:14
3  
@authchir: The part where you return a reference to a temporary object. That is and always has been UB. –  DeadMG Dec 3 '11 at 16:19
    
I've just add an update version in the initial question. What do you think of it? –  authchir Dec 3 '11 at 17:42
    
@authchir: It's not UB anymore. But your fundamental design is still a poor idea- why restrict users from using their intended derived class directly? For example, you now enforce a static lifetime, whereas a user may prefer a dynamic lifetime. –  DeadMG Dec 3 '11 at 20:49
    
Hmm? UB? Say you have a class with move semantic, you create it on the stack and then push into vector, as far as I know it should work just fine. Perfect forwarding or something like that. This actually solves the problem for classes that can have trivial move constructor and very complicated, or even impossible copy construction. –  Coder Dec 9 '11 at 20:55

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.