2

Here is the problem — I have two classes like this:

class A
{
  //some fields and methods 
   void niceMethod();
};

class B : public A
{
   void niceMethod();
};

class C : public A
{
   void niceMethod();
};

and function

void myFunc(A** arrayOfABC);

//Double * is to notice that I am going to modify the argument.

And I want to do:

(*arrayOfABC)[i].niceMethod();

in my function, getting different things done when I pass array of Bs or Cs to function.

But then I try to call it like

 B* bees = NULL;
    myFunc(&bees);

I have "Argument type of B** is incompatible with parameter of type A**".

I know that I can pass B or C as A to functions like f(A), but what's wrong with pointers?

2
  • 1
    Is something like this acceptable to you? B* bees = NULL; A* ptrs [] = {bees}; myFunc(ptrs); Commented May 31, 2012 at 15:21
  • Nice solution, but I decided to re-think my projectc structure at all to avoid this problem. Commented Jun 1, 2012 at 5:06

2 Answers 2

3

The compiler is right, it is indeed incompatible. Consider this:

B* bees = new B[2];
myFunc(&bees); // Imagine that it's allowed

Now inside myFunc you do this:

void myFunc(A** arrayOfABC) {
    // This is OK:
    arrayOfABC[0] = new C();
}

This should be allowed, because C extends A. However, upon return from myFunc your bees would contain a C, which is not good.

To fix this, create an array of A*, and populate it with pointers to B.

P.S. Don't forget to make niceMethod virtual, otherwise it's not going to work the way you expect.

Sign up to request clarification or add additional context in comments.

Comments

2

You can convert B* to A*, but not B** to A**.

Suppose A is fruit and B is apple, then A* is a little arrow that can point to a fruit (any fruit) and B* is a little arrow that can point to an apple (and only an apple). You can take an apple arrow, relabel it as a fruit arrow, and give it to somebody that expects fruit arrows. It indeed points to a fruit because an apple is a kind of a fruit. So far so good, no surprises here.

Now A** is a little arrow that can point to a little arrow that can point to a fruit (any fruit), and B** is a little arrow that can point to a little arrow that can point to an apple (and only an apple). What will happen if you take the latter, and give it to somebody who expects the former? That person can go along the arrow that can point to an arrow that can point to a fruit (any fruit!), take that second arrow, and turn it around and make it point to a banana.

Now the unfortunate apple guy guy who used to have a double-apple-arrow goes along the first arrow, then goes along the second arrow that ought to point to an apple, and finds a banana there, a fruit he sees the first time in his miserable life. That's a pretty unfortunate situation if you ask me. We shouldn't be surprised if things go bananas from this point on!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.