tags:

views:

73

answers:

3

Say you have a sub class B which inherits from super class A. You want a function that can accept either A or B.

template <typename T>
void someFunc(T* pObj, bool someOtherArg)
{
    pObj->AnInheritMethod();
    if (pObj->IsASub())
    {
       pObj->ANonInhertMethod();
    }
}

When I compile this (Visual Studio 6) I get:

error C2065: 'pObj' : undeclared identifier

Am I way off base here?

+2  A: 

You don't need templates for that, that is a free behaviour courtesy of polymorphism.

Edit: also if you write something like:

if (pObj->IsASub())

then there's maybe something wrong in your design. The method is supposed to work for any type in the derivation chain.

vulkanino
@vulkanio, thanks, the IsASub was just an oversimplification. The super class a method to determine which sub class it can be cast too.
Mark
that is the point, you shouldn't *need* to know the type :)
vulkanino
@Mark: There's one in the language, it's dynamic_cast.
DeadMG
+2  A: 

You don't need a function template for this; the following will do just fine:

void someFunc(A* pObj)
{
    pObj->AnInheritMethod();
    if (B* pObjAsB = dynamic_cast<B*>(pObj))
    {
        pObjAsB->ANonInheritMethod();
    }
}

Or, if you prefer to use your IsASub() member function instead of dynamic_cast:

void someFunc(A* pObj)
{
    pObj->AnInheritMethod();
    if (pObj->IsASub())
    {
        B* pObjAsB = static_cast<B*>(pObj);
        pObjAsB->ANonInheritMethod();
    }
}

Aside from the missing return type, I don't see anything obviously wrong with the code in your example; I don't have Visual C++ 6 installed to check.

James McNellis
While this answer is completely correct, the OP should note that the need to do this (check for a subclass and then perform a cast in order to call a non-inherited function) is nearly always indicative of poor object-oriented design.
Tyler McHenry
@Tyler: Perhaps. There are certain scenarios where casts make for simpler, cleaner code, and I think those scenarios are more common than many hard-line OOers admit.
James McNellis
+1  A: 

You're asking a question that is completely unrelated to the code and error that you included.

In order to have a function take an A or a class derived from A, all it needs to do is take a pointer or reference to A, e.g.

someFunc(A* pObj, bool someOtherArg);

or

someFunc(A& obj, bool someOtherArg);

It will work by virtue of inheritance. That's kind of the whole point of deriving classes from each other. The way you have written it with templates, it will work with any class that defines the three methods you use, whether or not it derives from A.

Now the error you posted is unrelated to this question but is bizarre. There's nothing wrong with the code you posted, but Visual Studio 6 is an ancient compiler; it's twelve years old and does not fully support modern ISO standard C++. This error may be an artifact of a sub-standard templating implementation in the compiler.

Tyler McHenry
Thanks. You are right, I think I somehow corrupted the project. Now that I've modified the code as described above, I get linker errors. Ughh, screw you ancient tools my company can't seem to let go of!!! At least I'm learning.
Mark