I've written a small example; note that if I change the call to
setValue(xy);
to
A::setValue(xy);
it compiles fine; but it seems to me that it should work without the A::,
since all the various setValue() routines are public, and I'm doing public
inheritance...
so what obvious thing am I missing (since both gcc 2.7.2 and CC on the SGI
complain, I must be wrong).
#include <iostream.h>
class A {
protected:
float _value[2];
public:
A() {
_value[0] = _value[1] = 0.0f;
}
void setValue(float* value) {
_value[0] = value[0];
_value[1] = value[1];
}
};
//////////////////////
class B : public A {
public:
B() : A() {
}
void setValue(float x, float y) {
_value[0] = x;
_value[1] = y;
}
};
//////////////////////
class C : public B {
protected:
float _timestamp;
public:
C() : B(), _timestamp(0.0f) {
}
void setValue(float timestamp, float* xy) {
_timestamp = timestamp;
//A::setValue(xy); // don't want to have to do this
setValue(xy);
}
};
main()
{
C *c = new C();
float a[2] = {3.3, 2.2};
c->setValue(0.0, a);
cout << "hi wave!\n";
return 1;
}
--
--> Michael B. Johnson, SMVS, Ph.D. -- wa...@pixar.com|wa...@media.mit.edu
--> Media Arts Technologist, Pixar Animation Studios (Eastern Office)
--> alumnus, MIT Media Lab, Computer Graphics & Animation Group
--> http://wave.www.media.mit.edu/people/wave/
[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
Let's simplify the problem:
class Base
{
public:
void f(int);
};
class Derived : public Base
{
public:
void f(int, int);
};
int main()
{
Derived d;
d.f(1); // error
}
The problem is that the two versions of f() are defined in different
scopes. This means that they do not overload, and the only version of
f() that can be called on an object of type Derived without using a
scope override is f(int,int).
The same problem arises in the original code: there is a definition of
setValue in C, and the versions in the base classes do not overload with
it. You can call the base version with an explicit scope qualifier or
you can give the base version of the function a different name.
Another approach is to hoist the base version into the derived class.
You can do this by writing a forwarding function in the derived class:
class Derived : public Base
{
public:
void f(int i) { Base::f(i); }
void f(int, int);
};
or, if your compiler supports this relatively new usage, you can add a
using declaration:
class Derived : public Base
{
public:
using Base::f;
void f(int, int);
};
The using declaration has the advantage that it pulls in all of the
versions of f from Base, without having to write a forwarding function
for each one. In this example it doesn't matter, but if there's more
than one (as in the original example, where B has two versions of
setValue, one defined in B and one hoisted from A with the same
technique) you can save some writing.
-- Pete
Well, Mike...
I doubt if this is any consolation, but when I read your thread I had to
agree with you when you said "this seems it should work, darn it!"
But I have just consulted my Lippman primer, and he says you can't do
this. Pgs. 401-3, Inherited Member Access, says:
"In most cases, use of the class scope operator is redundant. The
compiler can find the intended member without the additional lexical
aid. In two cases, however, this additional aid is necessary:
1. When an inherited member's name is reused in the derived class.
2. When two or more base classes define an inherited member with the
same name.
"Reuse of an inherited member's name within the derived class hides
the inherited member...
"When a name is reused by the inherited members of two or more base
classes, use of the unmodified name within the derived class is
ambiguous
and results in a compile time error. The class scope operator must be
used to disambiguate between the multiple instances of the inherited
members."
He even lists a somewhat similar example using zoo animals:
ZooAnimal::locate(void)
and
Bear::locate(int), where Bear is derived from ZooAnimal.
Sorry, dude.
Dave Hammond
Actually, this is FAQ 23.3. See there for an answer
(http://www.cerfnet.com/~mpcline/On-Line-C++-FAQs/).
Daveed
http://www.cerfnet.com/~mpcline/C++-FAQs-Lite/strange-inheritance.html#[2
3.3]
--
- Bill Seurer ID Tools and Compiler Development IBM Rochester,
MN
Business: BillS...@vnet.ibm.com Home:
BillS...@aol.com
WWW: http://members.aol.com/BillSeurer
> or, if your compiler supports this relatively new usage, you can add a
> using declaration:
>=20
> class Derived : public Base
> {
> public:
> using Base::f;
> void f(int, int);
> };
Is that real, working C++? Does any version of g++ support that yet?
Does using work with operators as well? Can I force inheritance of
operator=3D() (which to my knowledge isn't normally inherited) by
using Base::operator=3D; ?
Wondering why they eliminate the problems I have worked around so hard,
Harri Haanp=E4=E4