C++没有实现,但仍然可以调用它

No implementation in C++ but can still call it

本文关键字:调用 实现 C++      更新时间:2023-10-16

我有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并且不带参数。它不会创建名为 sSimpletron实例。

现在你可能会问,为什么链接器不抱怨不存在的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的实例,所以它永远不需要实际查找构造函数定义(尽管我认为它不能保证为了不给出错误,一个特别彻底的编译器/链接器夫妇应该能够给你一个缺少的构造函数的错误)。