考虑以下代码
class A {
int x, y;
public:
A(){}
virtual void PrintSize(){ cout << sizeof(typeof(*this)) << endl; }
};
class B : public A {
int a, b, c;
public:
B(){}
};
int main() {
A obja;
B objb;
obja.PrintSize();
objb.PrintSize();
}
“PrintSize()”的目的是获取我们调用它的当前类的大小。发生的情况是,即使我们从 B 调用它, this 关键字仍然引用类 A。我们不希望出现这种情况,因为我们需要这个函数对于子类是通用的。
我们显然可以为每个类逐字地重新定义函数。由于有太多不必要的行,代码将变得更难处理。更不用说为每个类重写函数会违背最初派生它的目的。
这是我的临时修复:
class A {
public:
virtual void PrintSize(){ cout << sizeof(typeof(*this)) << endl; }
};
class B : public A {
public:
virtual void PrintSize(){ cout << sizeof(typeof(*this)) << endl; }
};
class C : public A {
public:
virtual void PrintSize(){ cout << sizeof(typeof(*this)) << endl; }
};
class D : public A {
public:
virtual void PrintSize(){ cout << sizeof(typeof(*this)) << endl; }
};
最佳答案
虽然接受的答案可能已经解决了眼前的问题,但您突然没有 B
的公共(public)基类了。和C
。它们继承自两个不相关的类,即 A<B>
和A<C>
.
另一种方法是创建一个定义接口(interface)的公共(public)基础(下面称为 Interface
),并在派生类和接口(interface)之间添加 CRTP 类模板。这使您可以保留对 Interface
的指针和引用。并调用virtual
使用这些成员函数。
下面是在 vector
中存储指向公共(public)基类的指针的示例。 :
#include <iostream>
#include <memory>
#include <vector>
struct Interface {
virtual ~Interface() = default;
virtual void PrintSize() const = 0;
virtual void do_stuff() const = 0;
};
template<typename T>
struct Printer : public Interface {
void PrintSize() const override {
std::cout << sizeof(T) << '\n';
}
};
class B : public Printer<B> {
int a{};
public:
void do_stuff() const override { std::cout << "B doing stuff\n"; }
};
class C : public Printer<C> {
int a{}, b{}, c{};
public:
void do_stuff() const override { std::cout << "C doing stuff\n"; }
};
int main() {
std::vector<std::unique_ptr<Interface>> objs;
objs.emplace_back(std::make_unique<B>());
objs.emplace_back(std::make_unique<C>());
for(auto& ptr : objs) {
ptr->do_stuff();
ptr->PrintSize();
}
}
可能的输出:
B doing stuff
16
C doing stuff
24
关于c++ - 虚拟基类函数中派生类的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62311094/