C++ 继承和虚函数
C++ inheritance and virtual functions
阅读一本教科书后,我的印象是重写虚函数仅在使用指针或对象引用时有效。这本书演示了创建指向派生 class 类型的对象的基本 class 类型的指针,并使用它来演示虚函数覆盖。
但是,我现在遇到了以下情况。看不到指针,我原以为将 function1 设为虚拟不会有什么不同,但确实如此。我显然在这里遗漏了一些东西,希望能解释一下它是什么。对不起,如果我的解释不清楚;我也希望之前有人问过这个问题,但无法想出要搜索的内容。
using namespace std;
class ClassA
{
public:
void function1(); // virtual or not?
void function2();
};
class ClassB : public ClassA
{
public:
void function1();
};
int main()
{
ClassA objA;
ClassB objB;
objA.function1();
cout << "\n";
objA.function2();
cout << "\n";
objB.function1();
cout << "\n";
objB.function2(); // Fourth call
cout << "\n";
}
void ClassA::function1() { cout << "ClassA::function1\n"; }
void ClassA::function2()
{
cout << "ClassA::function2\n";
function1(); // For the fourth call ClassA::function1()
// is called if ClassA::function1() is not virtual
// but ClassB:function1() is called if it is. Why?
}
void ClassB::function1() { cout << "ClassB::function1\n"; }
非常感谢您的帮助。
它不是虚函数,因为它没有被标记为虚函数。它只是来自派生的 class / 对象的 public 函数 accessible。您的代码也没有表现出多态行为。也就是说 none 你的函数是 virtual nor overriding。多态安装的简单示例是:
#include <iostream>
#include <memory>
class ClassA {
public:
virtual void function1() { // now virtual
std::cout << "ClassA::function1\n";
}
};
class ClassB : public ClassA {
public:
void function1() override {
std::cout << "ClassB::function1\n";
}
};
int main() {
std::unique_ptr<ClassA> p = std::make_unique<ClassB>();
p->function1(); // now calls class B function, overrides class A behavior
}
或通过参考:
int main() {
ClassB objB;
ClassA& ro = objB;
ro.function1(); // now calls class B function, overrides class A behavior
}
如果您不使用多态行为,将函数标记为 virtual
和 override
没有什么好处。
function1 不是虚拟的,obj2 调用 classB function1 因为它是一个 clasB 对象,编译器首先查看函数的最派生类型,然后是最左边的基(并通过该基的基) ,然后是多重继承情况下的下一个基数。如果您将 classA * 带到 obj2 并调用 function1,它将调用 classA function1。
没有显式指针的虚拟示例:
class A
{
public:
virtual void f1()
{
cout << "A::f1()" << endl;
}
void f2()
{
f1();
}
};
class B : public A
{
public:
void f1() override
{
cout << "B::f1()" << endl;
}
};
int main()
{
A a;
B b;
a.f2();
b.f2();
}
阅读一本教科书后,我的印象是重写虚函数仅在使用指针或对象引用时有效。这本书演示了创建指向派生 class 类型的对象的基本 class 类型的指针,并使用它来演示虚函数覆盖。
但是,我现在遇到了以下情况。看不到指针,我原以为将 function1 设为虚拟不会有什么不同,但确实如此。我显然在这里遗漏了一些东西,希望能解释一下它是什么。对不起,如果我的解释不清楚;我也希望之前有人问过这个问题,但无法想出要搜索的内容。
using namespace std;
class ClassA
{
public:
void function1(); // virtual or not?
void function2();
};
class ClassB : public ClassA
{
public:
void function1();
};
int main()
{
ClassA objA;
ClassB objB;
objA.function1();
cout << "\n";
objA.function2();
cout << "\n";
objB.function1();
cout << "\n";
objB.function2(); // Fourth call
cout << "\n";
}
void ClassA::function1() { cout << "ClassA::function1\n"; }
void ClassA::function2()
{
cout << "ClassA::function2\n";
function1(); // For the fourth call ClassA::function1()
// is called if ClassA::function1() is not virtual
// but ClassB:function1() is called if it is. Why?
}
void ClassB::function1() { cout << "ClassB::function1\n"; }
非常感谢您的帮助。
它不是虚函数,因为它没有被标记为虚函数。它只是来自派生的 class / 对象的 public 函数 accessible。您的代码也没有表现出多态行为。也就是说 none 你的函数是 virtual nor overriding。多态安装的简单示例是:
#include <iostream>
#include <memory>
class ClassA {
public:
virtual void function1() { // now virtual
std::cout << "ClassA::function1\n";
}
};
class ClassB : public ClassA {
public:
void function1() override {
std::cout << "ClassB::function1\n";
}
};
int main() {
std::unique_ptr<ClassA> p = std::make_unique<ClassB>();
p->function1(); // now calls class B function, overrides class A behavior
}
或通过参考:
int main() {
ClassB objB;
ClassA& ro = objB;
ro.function1(); // now calls class B function, overrides class A behavior
}
如果您不使用多态行为,将函数标记为 virtual
和 override
没有什么好处。
function1 不是虚拟的,obj2 调用 classB function1 因为它是一个 clasB 对象,编译器首先查看函数的最派生类型,然后是最左边的基(并通过该基的基) ,然后是多重继承情况下的下一个基数。如果您将 classA * 带到 obj2 并调用 function1,它将调用 classA function1。
没有显式指针的虚拟示例:
class A
{
public:
virtual void f1()
{
cout << "A::f1()" << endl;
}
void f2()
{
f1();
}
};
class B : public A
{
public:
void f1() override
{
cout << "B::f1()" << endl;
}
};
int main()
{
A a;
B b;
a.f2();
b.f2();
}