0

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 by danizobin: n/a

4
Contributors
9
Replies
12
Views
7 Years
Discussion Span
Last Post by danizobin
0

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];
1

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.

0

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 by danizobin: n/a

1

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?

2

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.

0

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

0

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

0

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.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.