C++没有实现,但仍然可以调用它
No implementation in C++ but can still call it
我有Simpletron.cpp
,这是一个空文件,一个声明Simpletron
类的Simpletron.h
:
class Simpletron
{
public:
Simpletron();
};
我打电话给Simpletron()
.cpp:
#include <iostream>
#include "Simpletron.h"
int main(int argc, char *argv[])
{
Simpletron s();
std::cin.get();
}
主功能运行平稳,没有任何警告或错误。为什么?如果没有头文件可以链接到的实现,它甚至如何编译?
这一行:
Simpletron s();
是一个函数原型,声明一个名为 s
的函数,返回一个Simpletron
并且不带参数。它不会创建名为 s
的Simpletron
实例。
现在你可能会问,为什么链接器不抱怨不存在的s()
函数?好吧,由于您只是声明s()
但从未实际调用它,因此在链接期间实际上并没有在任何地方引用它,因此您不会收到链接错误。
Simpletron s();
这是函数声明,而不是对象实例化。空括号告诉编译器此函数不带参数,并返回按值Simpletron
类型的对象,因此不调用构造函数。正确的语法没有参数:
Simpletron s; // You will get an error on this line, as initially expected
C++11 添加了一个语法功能,避免了这种歧义:
Simpletron s{}; // same as default-initialization
Simpletron s();
这是"烦人解析"的经典案例;对于编译器,您不是在创建类型为 Simpletron
的变量s
,而是在声明一个名为 s
的函数,不带任何参数并返回一个Simpletron
对象。
这是因为这个表达式既可以解释为函数声明,也可以解释为变量声明;因为要声明变量,有一个简单的替代方法(即,只需省略括号)标准要求将其解释为函数声明。
这顺利通过了编译阶段(编译器不需要所有方法的定义,只需要声明),并且链接器可能不会给出任何错误,因为实际上没有创建Simpletron
的实例,所以它永远不需要实际查找构造函数定义(尽管我认为它不能保证为了不给出错误,一个特别彻底的编译器/链接器夫妇应该能够给你一个缺少的构造函数的错误)。
相关文章:
- C++中的单例实现在调用 getInstance 函数时不会产生相同的类实例
- std::bind 是否实现了 std::ref 和 std::cref 来消除函数调用的歧义?
- 了解使用堆栈实现队列的递归调用机制
- c++ 中的自定义分配器,用于不调用secure_string实现
- 在C++中实现类似 python "map"函数的问题:调用类成员函数
- 为什么在这种情况下不调用我的虚拟函数实现?
- 从C++调用dll实现的JNI
- 关于C++从派生类调用在基类中实现的虚拟函数的问题
- 当我从头文件和实现文件调用我的函数到我的主文件时,我没有得到任何输出
- 如何在子类中重写时调用私有虚拟基类实现
- 在实现和调用时可以复制函数参数名称吗?
- 调用没有主体的未实现静态方法
- 从用户定义的头文件调用函数时出现未定义的引用错误,其实现位于.cpp文件中
- 调用基类克隆实现
- 在调用函数上实现C++转换
- C++:调用运算符和调用其实现之间有区别吗
- 从多个不同的实现类 c++ 调用接口函数
- 在C++中调用 malloc() 与"operator new"函数之间的实现差异
- 重复调用实现矢量求和的成员函数的问题
- 使用 thrust::for_each() 调用实现 CUDA 流时访问结构的结果