Off*_*rmo 24 c++ forward-declaration
我刚接受采访.我被问到什么是"前瞻性声明".然后我被问到他们是否是与前瞻性声明有关的危险.
我无法回答第二个问题.在网上搜索没有显示任何有趣的结果.
那么,有人知道与使用前向声明有关的任何危险吗?
Mat*_* M. 15
好吧,除了有关复制的问题......
......标准中至少有一个疼痛部位.
如果调用delete指向不完整类型的指针,则会得到未定义的行为.实际上,析构函数可能不会被调用.
我们可以使用以下命令和示例在LiveWorkSpace上看到:
// -std=c++11 -Wall -W -pedantic -O2
#include <iostream>
struct ForwardDeclared;
void throw_away(ForwardDeclared* fd) {
delete fd;
}
struct ForwardDeclared {
~ForwardDeclared() {
std::cout << "Hello, World!\n";
}
};
int main() {
ForwardDeclared* fd = new ForwardDeclared();
throw_away(fd);
}
Run Code Online (Sandbox Code Playgroud)
诊断:
Compilation finished with warnings:
source.cpp: In function 'void throw_away(ForwardDeclared*)':
source.cpp:6:11: warning: possible problem detected in invocation of delete operator: [enabled by default]
source.cpp:5:6: warning: 'fd' has incomplete type [enabled by default]
source.cpp:3:8: warning: forward declaration of 'struct ForwardDeclared' [enabled by default]
source.cpp:6:11: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined
Run Code Online (Sandbox Code Playgroud)
你不想感谢你的编译器警告你;)?
我会说任何危险都会被收益黯然失色.但有一些,主要与重构有关.
namespace到另一个,再加上using指令,可能会造成严重破坏(神秘错误,难以发现和修复) - 当然,using指令很难开始,但没有代码是完美的,对吧?*考虑
template<class X = int> class Y;
int main()
{
Y<> * y;
}
//actual definition of the template
class Z
{
};
template<class X = Z> //vers 1.1, changed the default from int to Z
class Y
{};
Run Code Online (Sandbox Code Playgroud)
Z之后类被更改为默认模板参数,但原始前向声明仍然是int.
定义:
//3rd party code
namespace A
{
struct X {};
}
Run Code Online (Sandbox Code Playgroud)
和前瞻性声明:
//my code
namespace A { struct X; }
Run Code Online (Sandbox Code Playgroud)
//3rd party code
namespace B
{
struct X {};
}
namespace A
{
using ::B::X;
}
Run Code Online (Sandbox Code Playgroud)
这显然使我的代码无效,但错误不是在实际的地方,并且修复至少可以说是腥.
前向声明是C++ 缺少模块(将在 C++17 中修复?)和使用头文件包含的症状,如果 C++ 有模块,则根本不需要前向声明。
前向声明不低于“合同”,通过使用它,您实际上承诺您将提供某些东西的实现(在同一源文件中之后,或稍后通过链接二进制文件)。
这样做的缺点是您实际上必须遵守合同,这不是什么大问题,因为如果您不遵守合同,编译器会以某种方式提早抱怨,但在某些语言中,代码只需执行而无需“承诺其”自己的存在”(说到动态类型语言)
| 归档时间: |
|
| 查看次数: |
4203 次 |
| 最近记录: |