Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass subclasses to a function that takes their superclass

Let's say I have three classes - Animal, Cat and Dog, where Cat and Dog are subclasses of Animal (this does sound like the first lectures, but it's not homework I promise, just simplifying the real code)

Dog* spike = new Dog(); 
Cat* puss = new Cat();   

int main(int argc, char** argv)
{
    function(spike, puss);
    return 0;
}

void function(Animal *pet, Animal *pet2)
{
   magic->andSoForth();
}

Now this generates the following error:

Cannot convert parameter 1 from 'Dog *' to 'Animal'
  No constructor could take the source type,
    or constructor overload resolution was ambiguous

Changing the parameters to exactly match generates similar errors, only that it says it can't convert from a class to the same class.

I have successfully called the subclasses functions and members that they inherit from the superclass, so I know that this, logically, should work. I just don't know in what twisted way this language want me to bend logic.

EDIT

Solution happen to be: pointers confuse everyone.

  • Declare pointers.
  • Send pointers as arguments to a function that does NOT handle pointers.

In my example, I sent the "not-pointers" to the function that wanted pointers, I just switched that. Now it works fine.

like image 816
XistenZ Avatar asked Dec 02 '12 19:12

XistenZ


People also ask

Does a superclass inherit from a subclass?

A subclass inherits all the members (fields, methods, and nested classes) from its superclass. Constructors are not members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass.

Can methods of subclass be accessed by the super class?

Does a subclass have access to the members of a superclass? No, a superclass has no knowledge of its subclasses.

Can a superclass object be treated as a subclass object?

ANS: c. Objects of a subclass can be treated like objects of their superclass.

What is the connection between the subclass and the superclass?

Definition: A subclass is a class that derives from another class. A subclass inherits state and behavior from all of its ancestors. The term superclass refers to a class's direct ancestor as well as all of its ascendant classes.


2 Answers

When you dynamically allocate a new object, you get a pointer to that object. So you need to store it in a pointer like so:

Dog* spike = new Dog();
Cat* puss = new Cat();

You can then pass spike or puss for any parameter of type Animal*, assuming Dog and Cat do indeed inherit from Animal. This is the basics of polymorphism in C++:

A prvalue of type “pointer to cv D”, where D is a class type, can be converted to a prvalue of type “pointer to cv B”, where B is a base class (Clause 10) of D.

You could, of course, have stored them right away as Animal*:

Animal* spike = new Dog();
Animal* puss = new Cat();

Don't forget to delete them. Better yet, don't use new at all:

Dog spike;
Cat puss;
void function(const Animal&, const Animal&);
function(spike, puss);
like image 137
Joseph Mansfield Avatar answered Sep 24 '22 02:09

Joseph Mansfield


It's reasonable to assume that the problem you have is assigning a pointer to a non-pointer, or vice versa. But your code is not the real code, and your error messages are apparently not the real error messages. So it's all guesswork, in particular those already-posted answers that say "this is it" (it probably is, but not necessarily, and the uncertainty is entirely your own fault).


EDIT: the OP changed the question's code 10 seconds after I posted this.

The code still does not square with the purported error message.

I'm not going to chase this question as it changes.


Now, as to what to do…


Don't use new.

Experienced C++ programmers sometimes use new in controlled ways, wrapped in suitable code. Incompetent C++ programmers often use new as a matter of course. But in general, you don't need it, and it's problematic, so better as default don't use it.

Then, your program (which you neglected to show) would look like this:

#include <iostream>

struct Animal {};
struct Dog: Animal {};
struct Cat: Animal {};

void function(Animal const& pet1, Animal const& pet2 )
{
   //magicAndSoForth();
}

int main()
{
    Dog spike; 
    Cat puss;

    function( spike, puss );
}
like image 23
Cheers and hth. - Alf Avatar answered Sep 22 '22 02:09

Cheers and hth. - Alf