Can anyone explain why this doesn't work?

#include <iostream>

class Parent
{
  public:
    virtual int Add(int a, int b) = 0;

    int Add(int a)
    {
      return this->Add(a,a);
    }
};

class Child : public Parent
{
  public:
    int Add(int a, int b)
    {
      return a+b;
    }
};


int main()
{

  Child test;
  std::cout << test.Add(2);

  return 0;
}

It says:

error: no matching function call to 'Child::Add(int)'

The Child instance should be able to see the one argument Add function because it is inherited, right??

If I change the Child class to

class Child : public Parent
{
  public:
    int Add(int a, int b)
    {
      return a+b;
    }

    int Add(int a)
    {
      Parent::Add(a);
    }
};

It works fine. I thought the whole idea of inheritance was that I didn't specifically have to tell the derived classes about these functions?

Thanks,

David

Line 17: Child::Add takes 2 arguments. Line 28 calls Add with 1 argument.

I was wrong, it wouldn't be fixed if just to add 'virtual'.

In c++, if child class has a function with the same name with those in parent class (no matter they have same parameters or not between those functions in patent and child class), those functions in parent class would not be seen in child class. Actually just the case you are facing i think.

In my country, we call it 'overwrite', i'm not sure whether there is such a word in general C++.

Hope it helps.
Aidy

nezachem - no, I am trying to call the 1 argument version that should be inherited.

AidySun - I tried that and it didn't change anything.

Also note - if I change the one argument Add function to be called Test, everything works fine... this is very strange.

Ok, I found it. This is quite annoying... but there are 3 solutions (I got most of them from here: http://tuxdna.wordpress.com/2010/07/17/c-inheritance-and-function-overloading/)

1) Write using Parent::Add; in the derived class: (I show two derived classes to demonstrate why you would actually want to do this in the first place)

#include <iostream>

class Parent
{
  public:
    virtual int Add(int a, int b) = 0;

    int Add(int a)
    {
      return this->Add(a,a);
    }
};


class Child1 : public Parent
{
  public:
    using Parent::Add;
    
    int Add(int a, int b)
    {
      return a+b;
    }
};

class Child2 : public Parent
{
  public:
    using Parent::Add;

    int Add(int a, int b)
    {
      return a*b;
    }
};


int main()
{

  Child1 test1;
  std::cout << test1.Add(3) << std::endl;

  Child2 test2;
  std::cout << test2.Add(3) << std::endl;

  return 0;
}

2) Use this syntax std::cout << test1.Parent::Add(3) << std::endl;

#include <iostream>

class Parent
{
  public:
    virtual int Add(int a, int b) = 0;

    int Add(int a)
    {
      return this->Add(a,a);
    }
};

class Child1 : public Parent
{
  public:

    int Add(int a, int b)
    {
      return a+b;
    }
};

int main()
{

  Child1 test1;
  std::cout << test1.Parent::Add(3) << std::endl;

  return 0;
}

3) Define the function (that should be inherited...) to simply call the parent function:

int Add(int a)
    {
      Parent::Add(a);
    }
#include <iostream>

class Parent
{
  public:
    virtual int Add(int a, int b) = 0;

    int Add(int a)
    {
      return this->Add(a,a);
    }
};

class Child1 : public Parent
{
  public:

    int Add(int a, int b)
    {
      return a+b;
    }

    int Add(int a)
    {
      Parent::Add(a);
    }
};

int main()
{
  Child1 test1;
  std::cout << test1.Add(3) << std::endl;

  return 0;
}

Enjoy :)

David

And the reason why your original code didn't work is because your virtual add function
hid the 1 parameter function. Thats why you had to use the scope resolution operator.

4) Use are reference of the Parent type to call the overload:

#include <iostream>

class Parent
{
  public:
    virtual int Add(int a, int b) = 0;

    int Add(int a)
    {
      return this->Add(a,a);
    }
};

class Child1 : public Parent
{
  public:

    int Add(int a, int b)
    {
      return a+b;
    }
};

int main()
{

  Child1 test1;
  Parent& ref = test1;
  std::cout << ref.Add(3) << std::endl;

  return 0;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.