从基类获取派生类成员的大小

问题描述 投票:0回答:1
struct Base {
  uint8_t a{};
  uint8_t b{};
  size_t size() { return sizeof(*this); }
};

struct Derived: public Base{
  uint8_t c{};
};

int main() {
  Base* b = new Base();
  Derived* d = new Derived();
  std::cout << b->size() << "\n";  // prints 2 // correct
  std::cout << d->size() << "\n"; // prints 2 // incorrect, should be 3
}

我偶然发现了这个有趣的问题。我知道这是不正确的,因为我在这里没有使用虚函数。但如果我使用virtual,大小还包括vtable的大小。 如果我使用

virtual size_t size() { return sizeof(*this); }
,则两个 print 语句的输出都是 16。

如何在基类中编写一个函数,该函数将仅给出成员变量的总大小? 不知道是否有办法做到这一点

c++
1个回答
0
投票

在 C++23 中,您可以推导出传递给成员函数的

this
参数:

#include <iostream>
#include <cstdint>

struct Base {
  uint8_t a{};
  uint8_t b{};
  template <typename Self>
  size_t size(this Self&& self) { return sizeof(self); }
};

struct Derived: public Base{
  uint8_t c{};
};

int main() {
  Base* b = new Base();
  Derived* d = new Derived();
  std::cout << b->size() << "\n";
  std::cout << d->size() << "\n";should be 3
}

输出

2
3

但是,通常

sizeof(T)
不是
T
成员的大小(请参阅为什么结构体的 sizeof 不等于每个成员的 sizeof 之和?)。

此外,当某些东西可以作为自由函数而不是成员来实现时,那么这通常是更好的选择。在这里你实际上不需要实现任何东西,因为

sizeof(*b)
sizeof(*d)
确实已经产生了你想要的结果。

© www.soinside.com 2019 - 2024. All rights reserved.