1

I was wondering if I can't just ignore object slicing in a situation similar to the following:

class Base
{
  private:
    int8_t data[128];
    // other variables

  protected:
    Base(args) : args(args) { }
    void setData(uint8_t i, int8_t d) { data[i] = d; }

  public:
    void doSomethingWithData() { ... }
}

class Derived
{
  public:
    Derived(args) : Base(args)
    {
      setData(...);
      setData(...);
    }
}

Base array[] = {
  Derived(args),
  Derived2(args)
  ..
}

Base& any = array[0];

According to what I thought about object slicing, even if Derived specific copy/move constructor/assignment operators are lost, there is nothing to lose here so it could be a safe operation, assuming that any Derived limits itself to calling the Base constructor and setting some data. But this could be a typical pitfall that I'm overlooking.

Any guaranteed behavior about it?

Jack
  • 131,802
  • 30
  • 241
  • 343
  • 2
    What's the point of Derived class? Just make a function (static in Base or friend) which sets the data you require for that case. – Neil Kirk Jul 18 '14 at 13:32
  • @Neil Kirk: In reality I have like 15-20 Derived classes which represent png fonts (so with their own spacings and character widths). Each derived font exists in multiple colors too so it was nice to manage them in this way. Like `TinyFont(png, colors)`, `SmallFont(png, colors)`, etc – Jack Jul 18 '14 at 13:39
  • If the `Derived` doesn't introduce any additional state the object (member variable), you aren't going to loose anything, so it should be fine. I'd comment the code to that affect though, it may be obscure to a maintainer. – Niall Jul 18 '14 at 13:45
  • @Jack I once had a [similar problem](http://stackoverflow.com/questions/18251815/creating-an-array-initializer-from-a-tuple-or-variadic-template-parameters), works like a charm in the end ;) ... – πάντα ῥεῖ Jul 18 '14 at 13:46
  • Then have CreateTinyFont, CreateSmallFont functions etc. Not everything has to be a class. – Neil Kirk Jul 18 '14 at 15:16

2 Answers2

0

I'm not sure what you mean by "can I ignore slicing". Slicing will occur in your example, and you are obviously free to ignore it if you like but that will not change the behavior of the program. I don't see anything particularly wrong with your example though. I have written similar code on multiple occasions.

flodin
  • 5,215
  • 4
  • 26
  • 39
  • By ignoring I mean that I can assume that behavior will be correct regardless of slicing because no information (excluding the type) is lost. – Jack Jul 18 '14 at 13:36
  • In that case yes, you can make those assumptions. – flodin Jul 18 '14 at 13:56
0

Since the derived classes don't appear to add any state or polymorphic behavior it seems like slicing would functionally work here. But I'm going to suggest you still not do that.

I think a much more clear and idiomatic approach would be a line of functions that return the thing you're creating since you aren't using any of the reasons one migh invoke inheritance (typically substitution, occasionally privately inheriting an implementation):

Base TinyFont(png, colors) { /* create and return item */ }
Base SmallFont(png, colors) { /* create and return item */ }
Mark B
  • 95,107
  • 10
  • 109
  • 188