为什么不调用子类方法?
Why subclass method isn't called?
我在子类化和使用方法方面有问题。
我创建了一个类B
的实例,并将其存储为指向A
的指针。但是当我使用指针调用重载方法时,输出是"A"而不是"B"。为什么?
这在其他语言中有效,我做错了什么?
#include <iostream>
using namespace std;
class A {
public:
void f() {
cout << "A";
}
};
class B : public A {
public:
void f() {
cout << "B";
}
};
int main() {
A *a = new B();
a->f();
return 0;
}
f()
需要在基类A:中声明为virtual
class A {
public:
virtual void f() {
cout << "A";
}
};
你已经使用过的其他语言可能默认为虚拟方法,但C++没有(不要为你不使用的东西付费:虚拟方法在调用它们时会产生间接影响,这意味着它们比普通方法调用稍慢)。
通过添加virtual
,绑定将推迟到运行时(称为动态绑定),并且哪个f()
函数调用将取决于值的类型。
因为您尚未将函数f()
声明为虚拟,所以绑定是静态的(在编译时),并且将使用变量的类型(但不是值)来确定要调用哪个f()
。因此,在您当前的代码语句中,a->f();
调用A
类的f()
,因为a
是指向A
类的指针。
为了实现多态行为,基类的方法必须是virtual
。
因此,在class A
中,您需要将void f()
更改为virtual void f()
。
函数必须声明为virtual
才能覆盖它:
#include <iostream>
using namespace std;
class A {
public:
virtual void f() {// Here you must define the virtual.
cout << "A";
}
};
class B : public A {
public:
virtual void f() { //Here the "virtual" is optional, but a good practice
cout << "B";
}
};
int main() {
A *a = new B();
a->f();
return 0;
}
当没有指向基类的指针,而是指向基类的实际实例时,您可能会面临此问题(不适用于本问题中的示例)
在我的例子中,我有一个类Token
及其子类Word
:
class Token {
public: virtual string toString() { ... }
}
class Word: public Token {
public: string toString() { ... }
}
将它们存储在std::map<string, Token>
中并从中检索,我希望用这样的代码调用Word::toString()
:
std::map<string, Token> words;
words.insert("test", Word(...));
words["test"].toString();
相反,我每次都给Token::toString()
打电话。
解决方案:使用类似std::map<string, Token*>
的指针,并将所有实例视为指针(TBH,我已经讨厌指针了)
相关文章:
- 使用用户定义的参数调用future/async并调用类方法
- 重载类方法的不明确调用
- 绑定派生类方法C++从实例范围之外的分隔 std::function 变量调用
- 从基类实例调用派生类方法而不进行强制转换
- 派生类调用父类的方法,该方法调用重写的虚拟方法调用错误的方法
- 函数从唯一代码调用正确的子类方法
- C++ |DLL / EXE - 如何从导出的类调用另一个类方法?
- C++:从属性类调用顶级类方法
- 指向类方法调用的指针
- 有没有办法从同一类中的函子调用类方法?
- 有没有办法禁止派生类中的基类方法调用?
- 从类方法调用命名空间中名为 Same 的函数时,重载解析失败
- 我可以从析构函数的类方法调用它吗
- C++指向类方法调用的指针
- 基类方法调用派生类方法,任何可能的解决方案
- 从基类方法调用虚拟方法
- 非常具体的子类方法调用
- 类方法调用是否会在for循环中进行优化
- 使用具有相同声明的类方法调用全局函数
- 如何在c++中实现抽象类,同时允许子类方法调用