1

I'm rewriting a C++ application in Rust and I need to implement an array of pointers to the base class and populate the array with derived classes.

The C++:

BaseClass base[2] = new BaseClass[2];

base[0] = FirstDerivedClass ();
base[1] = SecondDerivedClass ();

FirstDerivedClass *fderived = dynamic_cast<FirstDerivedClass> (base[0]);

if (fderived != nullptr) {
   fderived.exclusive_method ();
}

I've tried to create something similar using Vec<Box<BaseTrait>> but there is no way to cast it to the appropriate derived class.

A solution with enum is not appropriate as there are great differences in size between the variants and I need to allocate several thousands of elements. This led me to combine a struct boxed in enum, but I don't know how to implement it.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
phodina
  • 1,341
  • 1
  • 12
  • 25
  • See also [this related question](https://users.rust-lang.org/t/how-to-downcast-from-trait-object/5852) on the Rust users' forum. – Sven Marnach Dec 18 '17 at 17:54
  • Also [this Q&A](https://stackoverflow.com/questions/27892375/can-i-do-type-introspection-with-trait-objects-and-then-downcast-it) – trent Dec 18 '17 at 18:06
  • 2
    *I'm rewriting a C++ application in Rust* — please consider *not* blindly transcribing paradigms from other languages directly to Rust. Rust is its own language with its own concepts, patterns, and best practices. – Shepmaster Dec 18 '17 at 18:11
  • 1
    Notice that `Vec>` and `Vec>` *both* store a piece of information indicating which type you're dealing with; with an `enum`, it's in line with the data itself, but with a boxed trait, it's part of the pointer. So `Vec>` requires less data storage for the values (and is similar to what C++ does), but `Vec>` actually requires less data storage for the `Vec` itself. – trent Dec 18 '17 at 18:14
  • 1
    It has been pointed out to me that the above comment may be misleading. The point I was trying to make is that "several thousands of elements" is not necessarily an argument in favor of trait objects; it can as easily go the other way, since there is a tension between "difference in size between the variants" and "number of references to elements". – trent Dec 18 '17 at 18:36
  • @Shepmaster I'm trying to rewrite the code not just in Rust but also by the patterns and concepts of the language. That being said I've read number of books on C/C++ and design patterns. Are you aware of some cookbook on Rust with solution to common problems (beside the Rust book & nomicon)? I'd like to escape downcasting as much as possible. – phodina Dec 18 '17 at 21:27
  • 1
    That will likely depend on the specifics of your problem. However, many patterns *do* translate. For example, [here's one example](https://stackoverflow.com/q/10718771/155423) of removing a specific type of downcasting. The "obvious" solution I see based on your code is to move `exclusive_method` to the trait and implement it as a no-op for things which don't need it. – Shepmaster Dec 18 '17 at 21:32

0 Answers0