【问题标题】:Forward declaration as struct vs class结构与类的前向声明
【发布时间】:2017-04-05 22:06:38
【问题描述】:

我在一个类的 C++ 前向声明中发现了一个错误,它被错误地声明为 struct Book 而不是 class Book。我认为 Book 曾经是一个结构体,现在变成了一个类,但前向声明仍然存在。

书.h:

class Book {
    ...
};

库.h:

struct Book;

class Library {
    std::vector<Book*> books;
};

没有编译器警告,生成的程序似乎运行良好。这让我很好奇:理论上,这会导致问题吗?它只是一个指针,是的,但是例如,如果类有虚方法,多重继承,指针会不同吗?

我知道类/结构在默认公共/私有方面的区别,但我特别询问前向声明以及交换它们的可能后果。

更新较新版本的 Xcode 现在会在出现不匹配时发出此警告:

Struct 'Book' was previously declared as a class; this is valid, but may result in linker errors under the Microsoft C++ ABI

【问题讨论】:

标签: c++ struct forward-declaration


【解决方案1】:

structclass 就前向声明而言是完全可以互换的。即使对于定义,它们也只影响对象成员的默认访问说明符,其他一切都是等价的。您总是定义对象的“类”。

class 上必须使用struct 的唯一地方是在为 绑定转发声明不透明数据时。


关于您的编辑:

我知道类/结构在默认公共/私有方面的区别,但我特别询问前向声明以及交换它们的可能后果。

Visual C++ 产生警告C4099。它会这样做,因为其功能的名称装饰包含您使用的关键字。因此,程序可能无法正确链接。因此,在使用 VC++ 时,完全符合标准的代码可能无法链接(AFAIC 是微软的愚蠢举动)。

可以在here找到有关此警告的讨论,以及如果您遵守纪律,为什么可以忽略它。

【讨论】:

  • 感谢您的回答。为了让您安心并避免任何编译器怪癖和可能的未来精神病维护者的愤怒,我将使所有前向声明匹配。
  • 这种行为是我当前任务所需要的。我需要对作为模板参数或宏参数传递的类型进行前向声明,但传递的类型可以是类或结构。
  • 这确实会导致 VC++ 中的链接器错误。见stackoverflow.com/questions/33483623/…
猜你喜欢
  • 1970-01-01
  • 2012-06-09
  • 1970-01-01
  • 1970-01-01
  • 2018-11-06
  • 2016-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多