我正在使用 googlemock 做一些有趣的事情,并决定将我的类分成纯虚拟类和具体实现,以避免需要为我的模拟使用特殊的外壳。然而,编译器开始提示:
error: undefined reference to 'vtable for <ConcreteClass>'
我成功地通过以下方式重现了该问题:
简单.h:
namespace simple {
class InterfaceA {
public:
virtual ~InterfaceA() {}
virtual int MethodOne() const = 0;
};
class InterfaceB : public InterfaceA {
public:
~InterfaceB() override {}
virtual int MethodTwo() const = 0;
};
class ImplA : public InterfaceA {
public:
ImplA(int to_return);
~ImplA() override {}
int MethodOne() const override;
private:
int to_return_;
};
class ImplB : public InterfaceB, public ImplA {
public:
ImplB();
~ImplB() override {}
// int MethodOne() const override;
int MethodTwo() const override;
};
} // namespace simple
简单.cc
#include "simple.h"
namespace simple {
ImplA::ImplA(int to_return) : to_return_(to_return) {}
int ImplA::MethodOne() const { return to_return_; }
ImplB::ImplB() : ImplA(5) {}
// int ImplB::MethodOne() const { return ImplA::MethodOne(); }
int ImplB::MethodTwo() const { return 2; }
} // namespace simple
问题是我注释掉的部分;一旦我将这些东西添加到文件中,编译器和我的测试都很满意。因此直观上这是有道理的,因为现在为虚拟方法定义了具体方法,而编译器以前不会/无法猜测我想要哪些父类(super class)方法。
我的问题有两个:
ImplA::MethodOne()
的规范如何允许调用它,因为它不是静态变量?- 在创建时,
ImplB
对象中的某处是否存在隐式ImplA
指针,允许它调用ImplA
上的方法,尽管该指针并未被调用静态方法?
最佳答案
您有菱形继承,因此从 InterfaceA 继承时需要指定 virtual 关键字。查看代码here
#include <iostream>
using namespace std;
namespace simple {
class InterfaceA {
public:
virtual ~InterfaceA() {}
virtual int MethodOne() const = 0;
};
class InterfaceB : virtual public InterfaceA { // <-- note the virtual keyword
public:
~InterfaceB() override {}
virtual int MethodTwo() const = 0;
};
class ImplA : virtual public InterfaceA { // <-- note the virtual keyword
public:
ImplA(int to_return);
~ImplA() override {}
int MethodOne() const override;
private:
int to_return_;
};
class ImplB : public InterfaceB, public ImplA {
public:
ImplB();
~ImplB() override {}
//int MethodOne() const override;
int MethodTwo() const override;
};
ImplA::ImplA(int to_return) : to_return_(to_return) {}
int ImplA::MethodOne() const { return to_return_; }
ImplB::ImplB() : ImplA(5) {}
// int ImplB::MethodOne() const { return ImplA::MethodOne(); }
int ImplB::MethodTwo() const { return 2; }
} // namespace simple
int main() {
simple::ImplA implA(100);
cout << implA.MethodOne() << endl << endl;
simple::ImplB implB;
cout << implB.MethodOne() << endl;
cout << implB.MethodTwo() << endl;
return 0;
}
顺便说一句,您在问题中写了一个静态方法...那里没有静态方法,当您调用 ImplA::MethodOne()
时,您实际上调用了 this->ImplA::MethodOne()
。因此,调用与 this
对象相关联。
关于c++ - 重新指定继承的虚拟方法如何使其能够正确消除歧义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36921974/