1

Possible Duplicate:
C++ method only visible when object cast to base class?!

I've the follow code:

class String {
    char* _Text;
public:
    String( const char* s ) {
        int iLen = strlen(s);
        _Text = new char [iLen+1];
        strcpy( _Text, s );
    }
};

template<typename T>
class Vector {
public:
    int Add( T* pItem ) { return 0; }
    int Add( const T* pItem ) { return 0; }
    int Add( T& pItem ) { return 0; }
};

class StrVector : public Vector<String> {
public:
    int Add( char* pItem ) { return 0; }
    int Add( const char* pItem ) { return 0; }
};

void main() 
{
    String s;
    StrVector v;
    v.Add( s ); <-------------
}

The line v.Add( s ); should call Vector::Add(T& pItem), right?

Community
  • 1
  • 1
Luciano
  • 11
  • 1
  • 2
    Duplicate: http://stackoverflow.com/questions/2068088/c-method-only-visible-when-object-cast-to-base-class – GManNickG Nov 09 '10 at 19:59
  • 2
    (1) `StrVector::Add` *shadows* `Vector::Add`; the lookup for `StrVector::Add` isn't going to look in the base class because it found the functions in the derived class. You can put `using Vector::Add;` in the definition to let them be found. (2) `String` needs to implement a destructor, which then entails you need [The Big Three](http://en.wikipedia.org/wiki/Rule_of_three_%28C%2B%2B_programming%29). (3) `Vector` either needs a virtual destructor or protected destructor; deleting through a base class pointer when it doesn't have a virtual destructor leads to UB. (4) `main` returns `int`! – GManNickG Nov 09 '10 at 20:03
  • 2
    (5) You should just be using `std::string` and `std::vector`. (6) You need to define "not work" when you ask questions: doesn't compile, doesn't do what you expect (and what did you expect) etc? Or I could have chosen any one of my points as an answer to "what's wrong". – GManNickG Nov 09 '10 at 20:03
  • http://www2.research.att.com/~bs/bs_faq2.html#overloadderived is another brief link to add to the pile, but I don't want to answer it as it is a duplicate. – Pete Kirkham Nov 09 '10 at 20:09
  • GMan's comments should be converted to an answer & then accepted – John Dibling Nov 09 '10 at 20:41
  • Please, GMan, convert your comments to an answer so I can accept it. Thanx for all! – Luciano Nov 10 '10 at 11:01

4 Answers4

2

The Add methods in the derived class hide the methods defined in the base class.

If you want the base class's Add to not be hidden, you can add a using directive to the derived class:

class StrVector : public Vector<String> {
public:
   using Vector<String>::Add;
   ...
}
sth
  • 222,467
  • 53
  • 283
  • 367
1

Nope. You are hiding all the Add functions ov Vector by declaring Add functions in class StrVector. The compiler is issuing an error, and it is right: int Add(String&) is not accessible.

Alexandre C.
  • 55,948
  • 11
  • 128
  • 197
1

I guess what you mean by "not working" is that the call to Add doesn't compile (no appropriate candidate, or something similar).

The Add methods declared in StrVector hide the ones from its base class. See Namespaces and the Interface Principle for a complete explanation.

icecrime
  • 74,451
  • 13
  • 99
  • 111
0

You never gave Vector an actual template argument, just said that it was a template. You need to have template<typename T>. Next, StrVector needs to inherit from Vector<char*>, although why you're inheriting from it I don't actually know.

Of cousre, in actual code, you'd use a std::vector<std:string>.

Puppy
  • 144,682
  • 38
  • 256
  • 465