>请考虑以下代码
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((" 的目的是获取我们调用它的当前类的大小。发生的情况是,this-关键字引用类 A,即使我们从 B 调用它。我们不希望这样,因为我们需要这个函数对子类是通用的。
我们显然可以逐字重新定义每个类的函数。代码将变得更加难以处理,因为有太多不合时宜的行。更不用说将函数重写到每个类会破坏首先派生它的目的。
这是我的临时修复:
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
和C
的共同基类。它们继承自两个不相关的类,即A<B>
和A<C>
。
另一种方法是创建一个定义接口的公共基(下面称为Interface
(,并在派生类和接口之间添加 CRTP 类模板。这使您可以保留对Interface
的指针和引用,并使用这些指针和引用调用virtual
成员函数。
下面是在vector
中存储指向公共基类的指针的示例:
#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 stuffn"; }
};
class C : public Printer<C> {
int a{}, b{}, c{};
public:
void do_stuff() const override { std::cout << "C doing stuffn"; }
};
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
您可以使用 CRTP 习惯用法来执行此操作。 https://eli.thegreenplace.net/2011/05/17/the-curiously-recurring-template-pattern-in-c 这个想法是父类是一个模板,因此您可以直接在其中访问子类的类型。 这样,您将能够从子类中删除所有"打印大小"。
例:
template <typename Derived>
class A {
int x, y;
public:
A() {}
void PrintSize() { cout << sizeof(Derived) << endl; }
};
class B : public A<B> {
int a, b, c;
public:
B() {}
};
class C : public A<C> {
public:
C() {}
};
int main() {
C objc;
B objb;
objc.PrintSize();
objb.PrintSize();
}
输出为:
8
20