2012-04-05 2 views
0

В следующем коде в функции set(int, int) класса Base я хочу назвать производную функцию класса showK(). Есть ли способ сделать это?Вызов функции производного класса из функции базового класса

Я не могу объявить showK() функцию в классе Base, и я не могу сделать это как виртуальное. Это ограничение для меня.

class Base{ 
    int i, j; 
    public: 
    void set(int, int); 
    void show() { cout << i << " " << j << "\n"; } 
}; 

void Base:: set(int a, int b) 
{ 
    i=a; j=b; 
    //Here I want to call the function showk() of class derived . Is there a way to call?. 
} 

class derived : public base { 
    int k; 
    public: 
    derived(int x) { k=x; } 
    virtual void showk() { cout << k << "\n"; } 
}; 

int main() 
{ 
    derived ob(3); 
    ob.set(1, 2); // access member of base 
    ob.show(); // access member of base 
    ob.showk(); // uses member of derived class 
    return 0; 
} 

Заранее благодарен.

+0

Так в чем проблема? – iehrlich

+1

Почему вы не можете сделать 'showk' чистым виртуальным? –

+1

Вы столкнулись с [принципом замещения Лискова] (http://en.wikipedia.org/wiki/Liskov_substitution_principle)? –

ответ

1

Вызов производного метода, когда объект не имеет такого типа, может привести к неопределенному поведению. Я думаю, что вы действительно хотите, чтобы метод set() вызывал showk(), если объект имеет тип производный. Это, как правило, можно сделать так:

class Base{ 
    int i, j; 
    public: 
    virtual void set(int, int); 
    void show() { cout << i << " " << j << "\n"; } 
}; 

void Base:: set(int a, int b) 
{ 
    i=a; j=b; 
} 

class derived : public base { 
    int k; 
    public: 
    derived(int x) { k=x; } 
    virtual void set(int a,int b); 
    virtual void showk() { cout << k << "\n"; } 
}; 

void derived::set(int a,int b) 
{ 
    base::set(a,b); 
    showk(); 
} 

int main() 
{ 
    derived ob(3); 
    ob.set(1, 2); // access member of base 
    ob.show(); // access member of base 
    ob.showk(); // uses member of derived class 
    return 0; 
} 
+0

Проблема в том, что база не имеет метода 'showk', просто' show'. – juanchopanza

+0

@juanchopanza: Я не вижу, как это проблема, поскольку это метод производного класса, вызывающий showk(). –

+1

Я понимаю, что OP хочет вызвать 'showk()' из 'Base :: set()' – juanchopanza

1

В функции множества (Int, Int) класса Base, я хочу назвать производной функции класса showK(). Есть ли способ сделать это? Я не могу объявить функцию showK() в классе Base, и я не могу сделать это виртуальным. Это ограничение для меня

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

void Base:: set(int a, int b) 
{ 
    i=a; j=b; 
    ((derived* const) this)->showk(); 
} 

Вы всегда можете сделать dynamic_cast вместо этого, чтобы проверить, является ли это производным, если вы хотите сделать что-то другое, если это не

(Сказав это, я бы предположил, что если вы находитесь в такой ситуации, чем что-то может быть не так с вашим дизайном. В целом базовые классы не должны «знать о» ИК производные классы.)

+4

Заменить «может быть неправильно» с «не так»;) –

+0

Я верю, что вы показываете здесь неопределенное поведение, даже если 'this' имеет правильный динамический тип. Вместо этого вы должны использовать 'static_cast (this)'. Ваш код может не работать при наличии множественного наследования. –

+0

@AlexandreC .: Это неверно. static_cast (x) точно эквивалентен ((T) x) и T (x). –

0
template <class derived_type> 
class Base{ 
    int i, j; 
    public: 
    void set(int, int); 
    void show() { cout << i << " " << j << "\n"; } 
}; 

template <class derived_type> 
void Base<derived_type>:: set(int a, int b) 
{ 
    i=a; j=b; 
    static_cast<derived_type*>(this)->showk(); 
} 

class derived : public Base<derived> { 
    int k; 
    public: 
    derived(int x) { k=x; } 
    virtual void showk() { cout << k << "\n"; } 
}; 

int main() 
{ 
    derived ob(3); 
    ob.set(1, 2); // access member of base 
    ob.show(); // access member of base 
    ob.showk(); // uses member of derived class 
    return 0; 
} 

http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern

Смежные вопросы