2

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();
}
Pierre.Vriens
2331 gold badge2 silver badges11 bronze badges
asked Dec 3, 2011 at 15:39
1
  • 1
    Generally speaking, rvalue references are an implementation detail, and class users should almost never be exposed to them. Commented Dec 4, 2011 at 10:12

1 Answer 1

3

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.

answered Dec 3, 2011 at 16:06
6
  • Which part is undefined? Return a Rvalue from a function or capture a Rvalue from a return object? Commented Dec 3, 2011 at 16:14
  • 4
    @authchir: The part where you return a reference to a temporary object. That is and always has been UB. Commented Dec 3, 2011 at 16:19
  • I've just add an update version in the initial question. What do you think of it? Commented Dec 3, 2011 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. Commented Dec 3, 2011 at 20:49
  • 1
    @Coder: He returned a reference to a local variable. That's UB. Commented Dec 11, 2011 at 15:41

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.