Thread: Virtual functions accepting inherited types

  1. #1
    Registered User
    Join Date
    Feb 2012
    Location
    Ottawa
    Posts
    6

    Virtual functions accepting inherited types

    I'm trying to write a set of matrix classes. There is a null base class, matrix_base, and three inherited classes: full_matrix, sparse_matrix, and sparse_array. All three inherited classes need to perform matrix multiplication (and other operations) with all three types, returning different types in each case. Why doesn't the following work:

    Code:
    class matrix_base {
      ...
      virtual matrix_base *mat_mult(matrix_base *cand)=0;
      ...
    };
    
    class full_matrix:public matrix_base {
      ...
      virtual full_matrix *mat_mult(full_matrix *cand);
      virtual full_matrix *mat_mult(sparse_matrix *cand);
      virtual full_matrix *mat_mult(sparse_array *cand);
      
      ...
    };
    
    class sparse_matrix:public matrix_base {
      ...
      virtual full_matrix *mat_mult(full_matrix *cand);
      virtual sparse_array *mat_mult(sparse_matrix *cand);
      virtual sparse_array *mat_mult(sparse_array *cand);
      
      ...
    };
    class sparse_array:public matrix_base {
      ...
      virtual full_matrix *mat_mult(full_matrix *cand);
      virtual sparse_array *mat_mult(sparse_matrix *cand);
      virtual sparse_array *mat_mult(sparse_array *cand);
      
      ...
    };
    In other words, I want to store all three types in a common base class, perform multiplications between them transparently and have them return the desired type so that I can repeat the process.

    C++ only allows me to define one of these virtual functions in each inherited class. Afterwards, it thinks that the function defines a field. Now there are two easy solutions to this.

    1. I can define all three functions in the base class:

    Code:
    class matrix_base {
      ...
      virtual matrix_base *mat_mult(full_matrix *cand)=0;
      virtual matrix_base *mat_mult(sparse_matrix *cand)=0;
      virtual matrix_base *mat_mult(sparse_array *cand)=0;
      
      ...
    };
    which requires a lot of forward declarations. Or, I can use if or switch statements to figure out which type is being passed to the inherited class:

    Code:
    class sparse_array:public matrix_base {
       ...
       virtual matrix_base *mat_mult(matrix_base *cand) {
        if (strcmp("sparse_matrix", (typeid(*cand).name)==0) { ...
      ...
    
    };
    In either case, it seems to me I'm doing C++'s job for it.

  2. #2
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    This is C++ we are talking about. Declarations are a thing that must be available.

    By the way, the way you are attempting to get parametric polymorphism and inheritance polymorphism at the same time isn't going to work the way you are probably going to want it to work to get the best performance possible out of sparse matrix multiplication even if you fixed the related problems.

    The reason being, none of these methods:

    Code:
    virtual full_matrix *mat_mult(full_matrix *cand);
    virtual sparse_array *mat_mult(sparse_matrix *cand);
    virtual sparse_array *mat_mult(sparse_array *cand);
    overrides this method:

    Code:
    virtual matrix_base *mat_mult(matrix_base *cand)=0;
    They are only overloads used in when they are the best option.

    So if you have a `sparse_matrix' object being referenced by a `matrix_base' pointer and make a call to `mat_mult' (as some_matrix->mat_mult(some_sparse_array)) you will not get a call to `virtual sparse_array *sparse_matrix::mat_mult(sparse_array *cand);', you will get a call to `virtual matrix_base *matrix_base::mat_mult(matrix_base *cand)=0;' and so have to perform a full inspection and multiplication in any event.

    Soma

  3. #3
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    C++ doesn't have multimethods. There are ways to kind of emulate them, though.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Cannot declare inherited class of virtual Base
    By rogster001 in forum C++ Programming
    Replies: 6
    Last Post: 12-17-2009, 10:25 AM
  2. Problem with functions in inherited classes
    By cableguy414 in forum C++ Programming
    Replies: 15
    Last Post: 08-30-2009, 10:56 AM
  3. Accepting Multiple Types of Input
    By Junior89 in forum C++ Programming
    Replies: 2
    Last Post: 03-07-2006, 11:25 PM
  4. Replies: 2
    Last Post: 10-02-2005, 05:04 PM
  5. Replies: 10
    Last Post: 08-18-2005, 01:17 AM

Tags for this Thread