【问题标题】:How do you distinguish the declaration of a class member function and data member如何区分类成员函数和数据成员的声明
【发布时间】:2016-10-12 06:56:53
【问题描述】:

你怎么能告诉编译器这是一个函数声明而不是数据成员:

typedef std::basic_ostringstream<char16_t> foostringstream;
class TextStream: public foostringstream {
    public:
        std::forward_list<TextInstruction> output();
};

问题是编译器 (VS2015.3) 出于某种恼人的原因,认为它是一个变量。

【问题讨论】:

  • 你是如何认为 VS 将其视为变量的?
  • 它吐出这个:warning C4820: 'Text::TextStream': '4' bytes padding added after data member 'Text::TextStream::output'
  • @Warpspace:无法在上述 sn-p 上的 VS2015 Update 3 中重现。或许还有别的原因?
  • MSVC 不太可能将output 视为变量。只是为了它,你可以试试:std::forward_list&lt;TextInstruction&gt; (output)();(见周围的大括号)。
  • 实际上我现在看到了:“警告 C4820:'TextStream':在数据成员 'TextStream::operator =' 之后添加了 '4' 字节填充”。所以,发生了一些奇怪的事情。

标签: c++ class syntax forward-declaration


【解决方案1】:

问题是您正在创建一个空类,这不是编译器问题。 想象一下你做了类似的事情

class Empty{}
int main() {
  Empty a,b;
  assert (&a == &b);
  cout << sizeof(Empty)
}

你希望结果是什么?

编译器总是添加填充以确保 &a != &b,这意味着 sizeof Empty 将 > 0(通常为 1)。

【讨论】:

  • 超类 (basic_ostringstream) 不应该为空。后来我添加了一个虚函数,导致创建了一个函数表,报错信息也是一样的。
  • 好吧,我知道如果您使用虚拟继承,则会添加更多填充,但还不知道为什么......我不知道标准中是否需要它,但我怀疑不是因为微处理器对内存的要求并不完全相同。
  • 前段时间我询问了关于标准的虚函数表,并被告知 VFT 根本不在标准中,因为编译器可能不使用 VFT。碰巧所有主要的编译器都使用它。因此,标准中不会有任何关于填充的内容。我确实怀疑填充的真正原因是 VFT,但如果是这样,那么错误消息极具误导性
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-08
  • 2011-11-23
相关资源
最近更新 更多