Hi,

New to this forum.
Will be happy for explanation for the next phenomenon:

class Base
{
protected:
void add(void *);
};

class Derived : public Base
{
public:
void add(int);
}

void Derived::add(int num)
{
add(new int(num));
}

This fails with the message:
Invalid conversion from 'int*' to 'int'
initializing argument 1 of 'void Derived::add(int)'

The following works:

void Derived::add(int num)
{
Base::add(new int(num));
}

Question:
The derived class should have inherited the void add(void*) method from base.
Then, there are two functions with the same name ('add') but different prototypes.
Why the derived doesn't see the "void add(void*)" defined in the Base?

Thank you

Edited 6 Years Ago by danizobin: n/a

probably because the compiler is using the public method from your derived class. Secondly why are you using a void * ? Third new is used to create objects on the free store. the proper syntax would be

int * number = new int;
int * numberArray = new int[50];

Derived class functions which have the same name as the base class functions hide the base class functions rather than overloading them. To allow overloading use the 'using' directive.

Nathan,

Thanks for answering

The answer to your second and third questions/remarks is: because it makes sense in the wider context of my program, which I didn't explain here.

And let me restate my question more specifically:
The function overloading mechanism should choose the function with the closest prototype to that of the call. Clearly this didn't happen in my case.
I guess there is another factor which I don't see, please help me to figure out which exactly

Edited 6 Years Ago by danizobin: n/a

do you want to have two separate add methods in you derived class? one that takes an int and one that takes a void pointer?

You haven't actually asked a question; you've made a claim. As it happens, that claim is false, and it is false for a good reason.

Consider:

class Foo { /* something */ };

class Bar: public Foo {
public:
    void f(double);
};

// ...

void x()
{
    Bar b;
    b.f(0);       // Which function is called?
}

If C++ were to behave as you claim it does, you would not be able to answer this question, because the answer would depend on whether class Foo defined a member f that accepted an int argument. So whenever you derived a function from a class that someone else had written, you would have to know the name and argument types of every function in that base class, just in case you happened to define a function with the same name yourself.

Even worse: Suppose a newer version of the base class came along and defined a function that did not exist in a previous version? All of a sudden, you would find the meaning of your code changed.

So what C++ actually does is to say that a derived class is a new scope. Except for virtual functions, very name defined in a derived class hides the corresponding name from any base classes. Although this rule sometimes behaves in ways that seem surprising, in most cases it is safer than the alternative.

do you want to have two separate add methods in you derived class? one that takes an int and one that takes a void pointer?

Yes

Then you should be able to make add virtual in your base class and than have another add with a different signature in your derived class

Then you should be able to make add virtual in your base class and than have another add with a different signature in your derived class

Nathan,

Do you mean that making the function virtual in Base, will prevent what people talked about here - the hiding phenomenon?
If so, I tried it - no difference after virtualizing add in Base.

This question has already been answered. Start a new discussion instead.