2010-09-23 2 views
0

у вас есть суб класс B, который наследуется от суперкласса А. Вы хотите функцию, которая может принимать А или В.C++ - функция Accept подклассов или супер

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

Когда я компилирую это (Visual Studio 6) Я получаю:

error C2065: 'pObj' : undeclared identifier 

Я ухожу от основания здесь?

+1

Прежде всего, вы должны объявить тип возврата для 'someFunc'. Во-вторых, создание версии 'A' этого метода (' someFunc ') завершится неудачно, поскольку' pObj' не будет определять методы производного класса (в этом случае AnInheritMethod). –

ответ

2

Для этого вам не нужен шаблон функции; следующий будет делать только штраф:

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

Или, если вы предпочитаете использовать IsASub() функции члена вместо dynamic_cast:

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

Помимо отсутствующего типа возврата, я не вижу ничего, очевидно, неправильно с кодом в вашем примере; У меня нет Visual C++ 6 для проверки.

+0

Хотя этот ответ абсолютно верный, OP должен отметить, что необходимость сделать это (проверить подкласс, а затем выполнить кастинг для вызова ненаследуемой функции) почти всегда указывает на плохой объектно-ориентированный дизайн. –

+0

@ Тайлер: Возможно. Существуют определенные сценарии, в которых броски делают более простой и понятный код, и я думаю, что эти сценарии более распространены, чем многие жесткие OOers допускают. –

2

Для этого вам не нужны шаблоны, то есть бесплатная вежливость в отношении полиморфизма.

Edit: также, если вы пишете что-то вроде:

if (pObj->IsASub()) 

то есть, возможно, что-то не так в вашем дизайне. Предполагается, что этот метод работает для любого типа в цепочке деривации.

+0

@vulkanio, спасибо, IsASub был просто упрощением. Суперкласс - это метод для определения того, какой подкласс он может быть отличен. – Mark

+1

, это то, что вам не нужно * нужно знать тип :) – vulkanino

+0

@Mark: В языке есть один, это dynamic_cast. – Puppy

1

Вы задаете вопрос, который полностью не связан с кодом и ошибкой, которые вы включили.

Для того чтобы функция имела A или класс, полученный от A, все, что нужно сделать, это взять указатель или ссылку на A, например.

someFunc(A* pObj, bool someOtherArg); 

или

someFunc(A& obj, bool someOtherArg); 

Он будет работать в силу наследования. В этом и заключается всякая связь между классами. То, как вы написали его с помощью шаблонов, будет работать с любым классом, который определяет три метода, которые вы используете, независимо от того, происходит он от A.

Теперь ошибка, которую вы опубликовали, не связана с этим вопросом, но причудлива. В коде, который вы опубликовали, нет ничего плохого, но Visual Studio 6 является древним компилятором; ему двенадцать лет, и он не полностью поддерживает современный стандарт ISO C++. Эта ошибка может быть артефактом реализации нестандартного шаблона в компиляторе.

+0

Спасибо. Вы правы, я думаю, что я как-то испортил проект. Теперь, когда я изменил код, как описано выше, я получаю ошибки компоновщика. Ухх, прикрутите к вам древние инструменты, которые моя компания не может отпустить !!! По крайней мере, я учусь. – Mark