2016-05-30 4 views
0

Я действительно не понимаю, почему это работает так.Почему это работает так?

#include<iostream> 

using namespace std; 
class Figura{ 
public: 
int x; 
int y; 
virtual void pomak(int dx=10,int dy=1) 
    { 

     x+=dx; 
     y+=dy; 
     cout<<"Figura"<<endl; 


    } 
}; 
class Skakac:public Figura{ 
public: 
void pomak(int dx=2,int dy=-1) 
    { 
     cout<<dx<<endl; 
     x+=dx; 
     y+=dy; 
     cout<<"Skakac"<<endl; 


    } 
}; 

int main() 
{ 
    Skakac S; 
    S.x=0; 
    S.y=0; 
    Figura* x=&S; 
    cout<<x->x<<" "<<x->y<<endl; 
    x->pomak(); 
    cout<<S.x<<" "<<S.y<<endl; 




} 

Когда я вызвать функцию помаки() это couts ого, как 10, хотя он вызывает вторая функция помаков (не виртуальный) и я четко указан, что де = 2.

+0

Изменение значений по умолчанию в переопределенных виртуальных функций ... пожалуйста, нет :( – Borgleader

+1

не могли бы вы придумать лучшее название? Один начинает думать, это о этом PTR. – user2672165

ответ

2

В соответствии со стандартом (N4140):

8.3.6 аргументы по умолчанию
...
вызов виртуальной функции (10.3) использует DEFA ult аргументы в объявлении виртуальной функции определены статическим типом указателя или ссылки, обозначающей объект. Функция переопределения в производном классе не принимает аргументы по умолчанию из функции, которую она переопределяет. [  Пример:

struct A { 
    virtual void f(int a = 7); 
}; 
struct B : public A { 
    void f(int a); 
}; 
void m() { 
    B* pb = new B; 
    A* pa = pb; 
    pa->f(); // OK, calls pa->B::f(7) 
    pb->f(); // error: wrong number of arguments for B::f() 
} 

-end пример]

+0

Как я могу это исправить? Я хочу иметь значения по умолчанию в виртуальных и первостепенных функциях –

+0

не уверен, если это это хорошая идея, но вы можете сделать виртуальную функцию 'getDefaults (int & dx. int & dy)' и переопределить ее по мере необходимости. – AlexD

+0

Что вы mea n этим? Вы можете поместить в коде для меня –

1

Эта функция вызывается через указатель на Figura. Значение по умолчанию для аргумента явно 10.

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

P.S.

он вызывает вторую функцию помаков (не виртуальный)

Skakac::pomak также является виртуальным.

Как я могу это исправить?

Если под «исправить это» вы имеете в виду «Как я могу переопределить аргумент по умолчанию», то я рекомендую использовать перегрузки вместо аргументов по умолчанию:

class Figura { 
    // ... 
    virtual void pomak() { 
     pomak(10, 1); 
    } 
    virtual void pomak(int dx, int dy) { 
     // ... 
    } 
}; 
class Skakac: public Figura { 
    // ... 
    void pomak() { 
     pomak(2, -1); 
    } 
    void pomak(int dx, int dy) { 
     // ... 
    } 
}; 
+0

Как я могу это исправить?Я хочу иметь значения по умолчанию как в виртуальных, так и в переопределяющих функциях. –

+0

@rusherzythaman см. В редакции. – user2079303

+0

@ user2079303 В этом случае может быть довольно запутанным иметь как 'pomak()', так и 'pomak (int, int)' virtual ... – AlexD