Могут ли виртуальные функции иметь параметры по умолчанию?

У меня есть небольшой инструмент, где я могу быстро запустить небольшие тестовые файлы в браузере и сразу получить результаты:

Проверка скорости JavaScript

Вы можете играть с кодом и узнать, какой метод лучше в тестируемом браузере.

148
задан John Dibling 27 August 2013 в 15:42
поделиться

3 ответа

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

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

3
ответ дан 23 November 2019 в 22:16
поделиться

Это была тема одной из первых сообщений Гуру недели Херба Саттера.

Первое, что он говорит по этому поводу, - НЕ ДЕЛАЙТЕ ЭТОГО.

Более подробно, да, вы можете указать другие параметры по умолчанию. Они не будут работать так же, как виртуальные функции. Виртуальная функция вызывается для динамического типа объекта, а значения параметров по умолчанию основаны на статическом типе.

Учитывая

class A {
    virtual void foo(int i = 1) { cout << "A::foo" << i << endl; }
};
class B: public A {
    virtual void foo(int i = 2) { cout << "B::foo" << i << endl; }
};
void test() {
A a;
B b;
A* ap = &b;
a.foo();
b.foo();
ap->foo();
}

, вы должны получить A :: foo1 B :: foo2 B :: foo1

36
ответ дан 23 November 2019 в 22:16
поделиться

Это тот вопрос, который, вероятно, можно достаточно хорошо выяснить с помощью тестирования (т.е. это достаточно распространенная часть языка, и большинство компиляторов почти наверняка делают это правильно, и если вы не видите различий между компиляторами, их вывод можно считать достаточно авторитетным).

#include <iostream>

struct base { 
    virtual void x(int a=0) { std::cout << a; }
    virtual ~base() {}
};

struct derived1 : base { 
    void x(int a) { std:: cout << a; }
};

struct derived2 : base { 
    void x(int a = 1) { std::cout << a; }
};

int main() { 
    base *b[3];
    b[0] = new base;
    b[1] = new derived1;
    b[2] = new derived2;

    for (int i=0; i<3; i++) {
        b[i]->x();
        delete b[i];
    }

    derived1 d;
    // d.x();       // won't compile.
    derived2 d2;
    d2.x();
    return 0;
}
4
ответ дан 23 November 2019 в 22:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: