Trouble with extending a class

Hello all. I haven't touched C in almost a decade, but I'm trying to re-teach myself the basics so that I can make full use of my Duemilanove. I created the following example to test the concept of extending a class. classTest is the original class and extendedClassTest is the derived class. As long as I call a unique procedure name, everything works fine.

For instance, a call to return100 returns 100 correctly. The problem is when I have a procedure with a duplicated name, but different arguments such as returnVal(char*). The compiler only seems to recognize the returnVal(float) that's defined in the derived class and doesn't see the original procedures at all. In the final code snippet (testMyClass.pde), the first class call to return100 works, but the next call to returnVal(char*) causes this error:

In function 'void setup()':
error: no matching function for call to 'extendedClassTest::returnVal(char [80])'C:\arduino\libraries\extendedClassTest/extendedClassTest.h:14: note: candidates are: float extendedClassTest::returnVal(float[

Any help you can provide would be greatly appreciated!

//-----------classTest.h-------------
#ifndef classTest_H
#define classTest_H

#include <Wprogram.h>
 
class classTest
{
  public:
    classTest();
    ~classTest();
    int returnVal(int);
    char* returnVal(char*);
    int return100();
};

#endif
//-----------classTest.cpp-------------
#include <classTest.h>

classTest::classTest(){
}
  
classTest::~classTest(){
}

int classTest::returnVal(int a){
  return a;
}

char* classTest::returnVal(char* a){
  return a;
}

int classTest::return100(){
  return 100;
}
//-----------extendedClassTest.h-------------
#ifndef extendedClassTest_H
#define extendedClassTest_H

#include <Wprogram.h>
#include <../classTest/classTest.h>

class extendedClassTest : public classTest
{

  public:
    extendedClassTest();
    ~extendedClassTest();
    float returnVal(float);
};

#endif
//-----------extendedClassTest.cpp-------------
#include <extendedClassTest.h>

extendedClassTest::extendedClassTest(){
}

extendedClassTest::~extendedClassTest(){
}

float extendedClassTest::returnVal(float a){
  return a;
}
//-----------testMyClass.pde-------------
#include <classTest.h>
#include <extendedClassTest.h>

extendedClassTest myClassTest;

void setup(){
  char strTest[80]="test\0";
  Serial.begin(9600);
  Serial.println(myClassTest.return100());
  Serial.println(myClassTest.returnVal(strTest));
}

void loop(){
}

In the base class, you have this:

    char* returnVal(char*);

That function takes a pointer to a char array as an input argument.

In the sketch, you have this:

  char strTest[80]="test\0";
  Serial.begin(9600);

  Serial.println(myClassTest.returnVal(strTest));

strTest is NOT a pointer to a character array.

Try this:

  char *strTest = "test";
  Serial.println(myClassTest.returnVal(strTest));

Oops, I knew I was going to make that mistake sooner or later. Unfortunately, it doesn't solve the problem. I end up with the same error. It really seems like it just ignores the original functions with the same name.

 In function 'void setup()':
error: no matching function for call to 'extendedClassTest::returnVal(char*&)'C:\arduino\libraries\extendedClassTest/extendedClassTest.h:14: note: candidates are: float extendedClassTest::returnVal(float)

Any other thoughts? Thanks again.

It would appear that declaring a function name in the sub-class hides all definitions of that function name in the base class. Whether this is proper C++ behavior, or not, I don't know, but it feels reasonable.

The error message says the error is on line 14 of the .h file for the extended class. I think if it was saying what you think, that it would say the error was in the .pde file. I don't UNDERSTAND the error, however.

It's telling you that there is no definition of the function returnVal that takes a character pointer as an argument. It's also telling you that there is only one possible candidate for returnVal, and that is the one defined in the extending class.

Therefore, it appears as though the compiler no longer knows about the returnVal methods of the base class.

I'm certainly confused, but
The error is coming from the line that declares the float, not from a line in .cpp or .pde that tries to reference a (hidden) declaration. The error is on a specific line in the .h; if a declaration is missing its missing. It is not missing on one line.

Hmn, from my previous C days, I thought one of the purposes of extending a class was to add different argument types and return types. Unless I'm confusing that with my previous Java days. For instance, several people have posted about trying to extend the SoftwareSerial.print() function to add the ability to print floats. Does it make sense that I would have to create a new function called SoftwareSerial.printFloat()? I honestly don't know. Can anyone tell me if this is proper C++ behavior or not? If not, should we submit this as a bug?

Thanks again!

#include <../classTest/classTest.h>

Does it do any better if you just include <classTest.h> like you did above?

I'm not sure that this is a bug. The purpose of extending a class is to provide additional or different behavior from the base class. If the extending class is to provide additional behavior, new methods and data are added. If the extending class is to provide different behavior, existing methods are re-declared and redefined.

In your case, you are re-declaring returnVal, with a different argument type. That effectively hides the declaration(s) in the base class.

In order to keep the methods defined in the base class, you should not re-declare the same method name.

but (I would suggest) returnVal(char*) isn't redeclared. returnVal(float) is declared in addition.
I'm with jr: I would have expected the extended class to simply provide one overload for returnVal in addition to the existing declaration in the base class.

Well, some research suggests the OP is experiencing expected behaviour...

It's apparently referred to as "name-hiding". See the example at the bottom of the page at above link.

indeed as Mitch_CA has pointed out if in the extendedClassTest.h file you say:

//-----------extendedClassTest.h-------------
#ifndef extendedClassTest_H
#define extendedClassTest_H

#include <Wprogram.h>
#include <classTest.h>

class extendedClassTest : public classTest
      {
            
      public:
            extendedClassTest(int);
            ~extendedClassTest();
            using classTest::returnVal;  //the magic words!
            float returnVal(float);
      };

#endif

everything works

I like this discussion better:http://discuss.joelonsoftware.com/default.asp?interview.11.747017.4
The issue was likely decided this way because of fear of accidental confusion, so you have to be more explicit.

You guys are brilliant! Thank you very much! This makes my various "print" overrides much more streamlined!

Thanks again!