标题说明了一切(我不确定何时使用virtual
关键字)。在这种情况下,函数SaySomething()
应该是virtual
吗? (或者在使用指针时它可能只是virtual
?)
#include <iostream>
class A{
public:
void SaySomething(){
std::cout << "aaaaaa";
}
};
class B : public A{
public:
void SaySomething(){
std::cout << "bbbbbbb";
}
};
int main(){
A objectA;
B objectB;
objectA.SaySomething();
std::cout << std::endl;
objectB.SaySomething();
return 0;
}
答案 0 :(得分:3)
从技术上讲,在这种情况下,函数B::SaySomething
不需要virtual
:编译器知道每个对象的运行时类型,因此在两种情况下都会调用正确的方法。
但是,它与基类同名A::SaySomething
但不覆盖它的事实可能会误导代码的读者。如果您打算隐藏,而不是覆盖类A::SaySomething
中的B
,那么最佳做法是为成员函数指定一个不同的名称。
以下是重要的情况:
B b;
A &ab(b);
b.SaySomething(); // Calls B::SaySomething
ab.SaySomething(); // Calls A::SaySomething
更改引用同一对象的方式时的行为会改变方法的行为,而不是代码的读者所期望的行为。如果你使A::SaySomething
为虚拟,则两个调用都会产生相同的行为。
答案 1 :(得分:0)
如果你有:
class A {
virtual void f() { cout << 1 << endl; }
};
class B : public A {
virtual void f() { cout << 2 << endl; }
};
然后当你在这样的代码中使用它时:
A* a = new B();
a->f();
您的程序将编写2,因为您使用了virtual
。它动态地解析指向的对象是B类型,尽管指针是A类型。
如果你不使用virtual
,它将打印1并使用指针类型类中的函数。
答案 2 :(得分:0)
virtual
关键字是在C ++中启用polymorphism的关键字。您的示例严格来说是非多态的,因为方法调用解析是静态的。所以在你的例子中没有必要。
但是,如果你有......
class Shape {
virtual double area() = 0;
}
class Circle : public Shape {
virtual double area() {
return PI * r * r;
}
}
class Square : public Shape {
virtual double area() {
return h * w;
}
}
代码......
Shape* shapes[2];
shapes[0] = new Circle(1);
shapes[1] = new Square(1, 1);
for (int i=0; i<2; i++)
cout << "shape[" << i << "] area -> " << shapes[i]->area();
会打印圆圈和方块的区域......
shape[0] area -> 3.1415926..
shape[1] area -> 1