gpt4 book ai didi

C++ - 动态绑定(bind)和对象实例不访问派生方法

转载 作者:行者123 更新时间:2023-11-30 01:53:49 33 4
gpt4 key购买 nike

我已经有一段时间没有用 C++ 编写任何东西了,并且遇到了一些令人困惑的继承问题。

第一个问题 - 根据我的理解,如果从指向基类的指针调用派生方法,则派生类实现该方法的具有虚方法的基类应该调用派生方法。为什么它需要是一个指针?这是因为 vtable 的实现方式吗?如果是这样,为什么在实际规范中没有抽象实现细节?我试图理解为什么会这样。是否有时您希望调用基类,只有当对象不是指针时?我认为重点是指向对象的指针与这些对象的行为相似。

第二个问题 - 在下面的代码中,我运行了一个测试,以查看如果访问方法是指针,则调用派生类方法。然后,我回过头来尝试用同样的方法将实例变成指针,实现同样的绑定(bind)。但是,如果该类在任何时候都存储为对象实例,则没有允许我将该类用作派生类的转换。为什么是这样?例如,如果我使用相同的对象(在下面进一步说明)并将它们放入一个 vector 中,那么它就可以正常工作。

    #include <iostream>
#include <string>
#include <vector>
using namespace std;

class BaseClass {
public:
virtual void A();
virtual void B();
};

void BaseClass::A() {
cout << "In base A" << endl;
}

void BaseClass::B() {
cout << "In base B" << endl;
}

class DerivedClass1 : public BaseClass {
public:
void A();
void B();
};

void DerivedClass1::A() {
cout << "In Derived A" << endl;
}

void DerivedClass1::B() {
cout << "In Derived B" << endl;
}

int main(int argc, char** argv) {
string cmd;
BaseClass bc;
DerivedClass1 dc1;

vector<BaseClass> list;
list.push_back(bc);
list.push_back(dc1);

cout << "Calling by " << endl;
for(int i = 0; i < list.size(); i++) {
// There is no possible cast to BaseClass* that causes A or B to call the derived class
(dynamic_cast<BaseClass*>(&list[i]))->A();
(dynamic_cast<BaseClass*>(&list[i]))->B();
}


// However, the below code, although it stores the same addresses, etc. works fine.
vector<BaseClass*> list_ptrs;
list_ptrs.push_back(&bc);
list_ptrs.push_back(&dc1);

cout << "Outputting Pointers" << endl;
for(int i = 0; i < list_ptrs.size(); i++) {
list_ptrs[i]->A();
list_ptrs[i]->B();
}

getline(cin, cmd);
}

抱歉,如果我只是误解了一些非常基本的东西,但这似乎是动态绑定(bind)工作方式的不一致,而且我找不到合适的解释(所有谷歌返回的都是试图访问基类方法的人。 ..).

如有任何帮助,我们将不胜感激,谢谢,-亚历克斯

最佳答案

这是错误的:

    BaseClass bc;
DerivedClass1 dc1;

vector<BaseClass> list;
list.push_back(bc);
list.push_back(dc1);

您的 vector 只能存储 BaseClass 对象。尝试将 DerivedClass 填充到只能容纳 BaseClass 对象的东西中称为 object slicing,这是您不希望发生的。对象切片意味着——您正在“切片”DerivedClass 的属性,使其成为一个 BaseClass。

要么有一个 BaseClass 指针 vector ,要么有两个单独的 vector ,一个是 BaseClass 对象,另一个是 DerivedClass 对象。

vector<BaseClass*> theList;
theList.push_back(&bc);
theList.push_back(&dc1);

您现在应该看到虚函数按预期工作。

关于C++ - 动态绑定(bind)和对象实例不访问派生方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22767747/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com