未定义与已删除与未声明的函数
undefined vs. deleted vs. undeclared function
我在这里使用默认构造函数作为示例,但同样的问题适用于所有特殊成员函数。
此外,我正在使用 https://en.cppreference.com 而不是标准,因为这是我正在阅读的内容,这就是我难以理解的内容。如果使用标准会以任何方式改变问题,请告诉我。
如 https://en.cppreference.com/w/cpp/language/default_constructor 中所述,如果一个类没有构造函数,那么编译器将始终声明一个默认构造函数。然后,如果不满足某些条件,它将未定义(在 c++11 之前)或定义为已删除(在 c++11 之后)。
所有这些似乎都暗示着函数未声明、声明但未定义或声明和删除之间存在差异。但是,所有三个选项都不会编译/链接,例如
class MyClass {
public:
void foo();
void bar() = delete;
};
int main() {
MyClass c;
//c.foo(); // won't link
//c.bar(); // won't compile
//c.baz(); // won't compile
}
那么,为什么将定义从"声明和未定义"更改为"声明和删除"如此重要,为什么不首先将其保留为"未声明"呢?
那么,为什么将定义从"声明和未定义"更改为"声明和删除"如此重要
因为差异:"不会链接">与"不会编译"。这是引入= delete
的根本原因:在编译时而不是以后捕获使用(以前)未定义函数的错误。此外,它允许更好的错误诊断,因为编译器将能够描述删除函数的原因。链接器可以说的最好的是,由于某种未知的原因,没有人定义它。
没有理由不利用隐式生成的成员函数的功能。
= deleted;
声明在各种情况下都很有用。除了 eerorika 给出的很好的理由外,它还可用于显式声明给定的"特殊"函数(例如默认构造函数)不存在,并且无法调用。
它还可用于指定基类中存在的函数在派生类中不存在(默认情况下,派生类中不存在)。
下面是一段显示这种用法的简短代码:
#include <iostream>
class foo {
private:
int m;
public:
foo() = delete; // Other programmers reading this definition will know immediately!
foo(int n) : m{ n } {} // ... that default ctor is intended not to be used
void inc() { ++m; } // ... rather than it has been omitted accidentally
int get() { return m; }
};
class bar : public foo {
public:
bar() : foo(0) {}
void inc() = delete; // Without this, code like `bar b; b.inc();` will call foo.inc()
};
int main() {
// foo f1; // error C2280: 'foo::foo(void)': attempting to reference a deleted function
foo f2(3); std::cout << f2.get() << std::endl;
f2.inc(); std::cout << f2.get() << std::endl;
bar b1; std::cout << b1.get() << std::endl;
// b1.inc(); error C2280: 'void bar::inc(void)': attempting to reference a deleted function
return 0;
}
- 函数未在作用域中声明 / 如何结合使用 header.h、header.cpp 和 main.cpp?
- 我的函数调用 (C++) 中的未声明标识符
- 未定义与已删除与未声明的函数
- C++ 在 CentOS7 中与 g++ 的 DLL 链接后未声明的函数
- 由于值返回函数中的错误,程序无法编译.它说未声明的标识符
- 为什么 C 允许我调用未声明的函数?
- 'temp'未声明,请先使用此函数
- C 如何从构造函数中声明(错误C2065未宣布的标识符)
- 函数未在此范围内声明
- 尝试使用 std::函数(未定义的符号)声明模板化类状态时出现链接错误
- makefile 和 lex+yacc 中的错误 -> 错误:"noyywrap"未声明(在此函数中首次使用)
- 我们如何有证据表明,声明虚拟函数的类是2个字节,其中一个不超过一个未声明,而在子类中
- 函数参数中未声明和未定义的标识符
- 在此范围错误中未声明函数错误
- 类 'MainWindow' 中未声明任何成员函数
- 错误C2509:成员函数未在派生类中声明
- C++成员函数未声明错误时(当它看起来是错误时)
- 函数未声明(首先使用此函数)
- 函数未声明简单程序
- 无法调用 VBO 实现所需的函数...未声明错误