Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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?

Edit

AS DeadMG pointed out, my initial make_base has undefined behaviour. If I can't require clients to only use Base class, I wish I could recommend 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
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
4  
@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
1  
@Coder: He returned a reference to a local variable. That's UB. – DeadMG Dec 11 '11 at 15:41

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.