0

Let me write the relation that A is a sub-class of B by A < B. Suppose there is a relation A < B < C between three classes.

Now, what I want to do is to define a function/class-method that can take argument of all A, B and C (all the sub-class of A). Is it possible? and if so, how can I do this?

EDIT: MOTIVATION The motivation of this is as follows: Let say I want to solve a maze. The solver function solve_maze takes a Maze and solve the maze. By default, is_obstacle_free is set to return true always. This means that default maze is the empty space.

What I want to do is, enabling the user to define their custom CustomMaze by inheriting the Maze class if they want. User can change the shape of the maze by tweaking the is_obstacle_free function. Maybe, another user want to define class CustomMaze2 inheriting from CustomMaze.

If I can define solve_maze function that accept any sub-type of Maze, we can avoid defining solve_maze anytime users added a new maze type.

class Maze
{
   virtual bool is_obstacle_free(Point p){
       return true;
   }
};

class CustomMaze : public Maze
{
  bool is_obstacle_free(Point p) override;
};

void solve_maze(Space s, Solution& sol){
   \\ call a lot of is_obstacle_free inside
}
orematasaburo
  • 1,207
  • 10
  • 20
  • 1
    Your parameter has to be a reference or pointer instead. However, you still can only access the members of that class type that you used as a parameter. – Timo Jun 03 '21 at 16:34
  • 2
    Does this answer your question? [What is object slicing?](https://stackoverflow.com/questions/274626/what-is-object-slicing) – Lukas-T Jun 03 '21 at 16:34
  • 1
    TL;DR version: They have not been cast. `sample` takes an `A` by value, so it copies the given argument into `a` and since `a` cannot hold a `B` or `C` but both are implicitly convertible to `A`, `a` is a new object that leaves out any `B`- or C`-ness. – user4581301 Jun 03 '21 at 16:39
  • 2
    Change `void sample(A a);` -> `void sample(A & a);` – Richard Critten Jun 03 '21 at 16:45
  • Polymorphism may also come in handy here ([example](https://godbolt.org/z/EYcG1854M)). Please describe what you want to do with the argument in `sample()`. – Ted Lyngmo Jun 03 '21 at 16:48
  • 2
    If you want to learn C++, I recommend getting a [good book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). The language is probably too complicated to learn by asking questions on stackoverflow. – n. m. could be an AI Jun 03 '21 at 16:50
  • @TedLyngmo OK, I write the motivation again. without casting of not is actually not the point here. I should have made the motivation clear. – orematasaburo Jun 03 '21 at 16:55
  • @orematasaburo You described nothing about what you expect to do with the argument inside `sample`. Did you look at my example? Also, I don't know anything about the julia language. – Ted Lyngmo Jun 03 '21 at 16:59
  • You can use templates and specify which types it can accept. – Martin Perry Jun 03 '21 at 16:59
  • @TedLyngmo I editted the motivation. – orematasaburo Jun 03 '21 at 17:11
  • @n.1.8e9-where's-my-sharem. Rather, the language is too complicated to learn by reading book, I guess. Anyway, I edited the question quite a lot. – orematasaburo Jun 03 '21 at 17:14
  • 1
    @orematasaburo Looks close to my example but you missed making it a reference. [Look here](https://godbolt.org/z/fTKjdjWc4) – Ted Lyngmo Jun 03 '21 at 17:19
  • 1
    It is still complicated, but a good book will teach you to ask better questions. – n. m. could be an AI Jun 03 '21 at 17:23
  • 1
    Your motivation can be simplified to this sentence: "I want bog-standard polymorphism". In C++ you get bog-standard polymorphism by using a pointer or a reference to a base class. – n. m. could be an AI Jun 03 '21 at 17:42
  • A good book can speed the learning of the language enormously. Watershed book for me was Effective C++. Probably a bit dated now, but at the time it was the bomb. – user4581301 Jun 04 '21 at 00:41

1 Answers1

1
void sample(A& a);

will accept anything that derives from A, but sample will only use a as if it were an A object (without casting).

With templates, you can do this without casting:

template <typename T>
void sample(T& t)
{
  static_assert(std::is_base_of<A,T>::value, "T must be derived from A");
  // T is whatever sample was called with.
}
erenon
  • 18,838
  • 2
  • 61
  • 93