Is object slicing ever useful?

女生的网名这么多〃 提交于 2019-11-30 17:27:28

Sure, it can be useful when wanting to drop the derived portion of class, perhaps to drop dependencies.

For example say we have an object system setup where each base belongs to a derived type, and each derived type has various dependencies, perhaps fulfilled through dependency injection. A clone of a base might want to be created, though a completely new set of dependencies for the actual derived type of that base may want to be assigned.

This can be likened to an game engine where there are many types of colliders. Each collider derives from a base interface-like object in various ways. We want to clone a collider to retrieve it's position and scale (from base), but want to place an entirely different derived implementation on-top of this base. "Object slicing" could be a simple way to achieve this.

In reality a component, or aggregate object organization would make a lot more sense than object slicing specifically, but it's mostly the same idea.

Some STL implementations actually use object slicing to implement algorithms: E.g., using iterator_tags you can easily make std::advance use the most efficient algorithm:

namespace std {

template <class I>
void advance_impl(I& it, int n, input_iterator_tag) {
    for (; n > 0; --n)
        ++it;
}

// Forward Iterators use the same implementation as Input Iterators...

// TODO:
// Add bidirectional_iterator_tag implementation...

template <class I>
void advance_impl(I& it, int n, random_access_iterator_tag) {
    it += n;
}

template <class I>
void advance(I& it, int n) {
    advance_impl(it, n, typename iterator_traits<I>::iterator_category());
}

} // std

Using your own little class hierarchy you can disambiguate otherwise ambiguous function overloads. E.g. to convert an object to a std::string you might want to use the objects member function to_string() if it exists or otherwise use operator<<.

struct R2 {};       // rank 2
struct R1 : R2 {};  // rank 1

// C++11.
// Use some type traits and enable_if in C++03.
template <class T>
auto ToString(R1, T const& t) -> decltype(t.to_string()) {
    return t.to_string();
}

template <class T>
std::string ToString(R2, T const& t) {
    std::ostringstream s;
    s << t;
    return s.str();
}

template <class T>
std::string ToString(T const& t) {
    return ToString(R1(), t);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!