class A {
public:
virtualint func(int i = 1) {
std::cout << "class A" << std::endl;
return i + 1;
}
virtual ~A() {}
};
class B :public A {
public:
virtualint func(int i = 10) {
std::cout << "class B " << i << std::endl;
return i;
}
};
int main(int argc, char* argv[]) {
A* p = new B();
p->func();
delete p;
return 0;
}
The output of the code ("class B 1") confuses me. I wonder what happened. I think the key is the default arguments in virtual function.
Thanks for you help.
The default arguments are determined "statically" (at compile time), so as coder777 said, all it sees is that the A class is being dereferenced, so it applies A's default argument. It isn't until runtime that it looks up that it actually needs to call the subclass.
Unless you're really out to confuse people, don't change the default parameters of the inherited functions you override. (In general, it's not a bad idea to prefer overloading to parameter defaulting anyway, but that's a subject in itself.)
p is of type pointer A - so the default value from A.func() is used.
If p is made pointer to B, then the default value from B.func() is used.
Note that if a member function of a base class is being overridden, you can specify override on the overridden function so that the compiler can check that the function is indeed overridden. Also virtual is not needed for virtual overridden functions. Consider:
#include <iostream>
class A {
public:
virtualint func(int i = 1) {
std::cout << "class A\n";
return i + 1;
}
virtual ~A() {}
};
class B : public A {
public:
int func(int i = 10) override {
std::cout << "class B " << i << '\n';
return i;
}
};
class C : public B {
public:
int func(int i = 100) override {
std::cout << "class C " << i << '\n';
return i;
}
};
int main() {
B* p { new C };
p->func();
delete p;
}
#include <iostream>
class A {
public:
virtualvoid func(int i = 1) {
std::cout << "class A " << i << '\n';
return;
}
virtual ~A() {}
};
class B : public A {
public:
void func(int i = 10) override {
// i = 10; // new definition
std::cout << "class B " << i << '\n';
return;
}
};
int main()
{
A* p { new B };
p->func();
delete p;
}
If I understand correctly, when we use some virtual function (including parameters by default), we have to set the new parameters even if they are declared in the overriden function?
#include <iostream>
class A {
public:
virtualvoid func(int i = 1) {
std::cout << "class A " << i << '\n';
}
virtual ~A() {}
};
class B : public A {
public:
void func(int i) override { // OK
std::cout << "class B " << i << '\n';
}
};
int main()
{
B b;
A* p { &b };
p->func();
p->func(2);
B* r { &b };
r->func(3);
r->func(); // error: too few arguments to function call, expected 1, have 0;
}