cannot convert parameter 1 from 'B *' to 'A *&'

sory i know i wou might be bored..

i receive this error in following code

'f' : cannot convert parameter 1 from 'B *' to 'A *&'


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class A{
public:
	int a;
	A() {a=34;}
	A(int i){a=i;}
	virtual void print(){cout<<a;}
};
class B:virtual public A
{
public:
	int b;
	B() {b=64;}
	B(int i){b=i;}
	virtual void print(){cout<<b;}
};
void f(A * &bp)
{
	bp->print();
}
int main()
{

B *b=new B;

f(b);
cin.ignore().get();
return 0;
}



any idea why??
Yeah. On line 23, you create a B*, then pass it to f(), which only takes a reference to an A*.
but B is an A..
I think that derived objects can be given to base objects..
or not??
Last edited on
You shouldn't need to use a reference if you're using a pointer already. Get rid of the & in the function declaration, and you can do what you like with it. If you wish, you can make it a const pointer to an instance of the A class to simulate the effect of a reference:
1
2
3
4
5
void
f (A *const bp)
{
  bp->print ();
}
if i passed the object not the pointer then could i pass with reference??

1
2
3
4
5
void
f (A & bp)
{
  bp.print ();
}


and why??
B is an A, this is true.

However B* is not an A*. The tricky bit is that B* can be cast to an A*, but this does not mean it is an A*.

The reason your original post did not work was because b was being cast to an A* as a temporary, unnamed object, then that object was passed by non-const reference to a function. This is illegal, because it can do one of two things, and neither one is what you want.

Here's an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class A { };
class B : public A { };
class C : public A { };

void f(A*& a)
{
  a = new C;  // perfectly legal, C is an A
}

int main()
{
  B* b;
  f(b);  // ??  see notes below
}


What would you expect this code to do?

1) In C++, the function call gives you a compiler error for the above reason. You can't pass a temporary object by non-const reference.

or

2) If for some reason the call compiled okay... f() would change a temporary object and would not be changing 'b' as you'd expect. This would result in runtime errors because the function doesn't do what you expect it to, and also memory leaks in this case because the temporary object can never be deleted.

or

3) If neither of the above happen, and 'b' is changed appropriately... then 'b' now points to a C! But a B isn't a C! Basically it makes 'b' become a bad pointer, and could wreck havok on your program if you tried to dereference it.



1
2
3
4
5
void
f (A & bp)
{
  bp.print ();
}



This code works because a B is an A, so you can pass a B as an A&.

Just remember: B is an A... but a B* is not an A*.
"In C++, the function call gives you a compiler error for the above reason. You can't pass a temporary object by non-const reference."

1
2
3
4
5
6
7
8
9
void
f (A & bp)
{
  bp.print ();
}
int main(){
B b;
f(b);
}



in this case is the b not a temporary object??
and i think we pass it with the same way (non-const reference)

why does it work?
i dont understand the difference..



in this case is the b not a temporary object??


No, b is not temporary because you're passing b.

Let me try to explain further. Here's what we're looking at:

1
2
3
4
5
6
7
8
9
10
11
12
13
void good(A& p) { }
void bad(A*& pr) { }

int main()
{
   // good
   B b;
   good(b);  // OK

   // bad
   B* p;
   bad(p);  // error
}


good works because a B is an A. Anywhere you can use A, you can also use a B. Therefore, when you call good(b), the compiler does not have any problem, because b is a B, which also makes it an A. No temporary object needs to be created and b can get passed directly to the function.


bad fails because a B* is not an A*. You cannot use a B* as if it were an A*, therefore the compiler needs to cast B* to A*. Since there is a cast involved, it needs to create a temporary object. This temporary object is being passed to the function. 'b' is not being passed.

It's like it's doing this:

1
2
3
4
  // bad
   B* p;
   A* temporary = p;
   bad(temporary);


Here the temporary object is being passed by non-const reference, so any changes to to 'pr' in bad() will change 'temporary' and will not change 'p'. Since this would be an unwanted side-effect and a source of many hard to find bugs, C++ simply doesn't allow you to do that and gives you that compiler error.
Topic archived. No new replies allowed.