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

oct*_*ref 8 c++

我有Simpletron.cpp一个文件,Simpletron.h它声明了一个Simpletron类:

class Simpletron 
{    
public:
    Simpletron();
};
Run Code Online (Sandbox Code Playgroud)

我打电话给Simpletron()我的main.cpp:

#include <iostream>
#include "Simpletron.h"

int main(int argc, char *argv[]) 
{

    Simpletron s();
    std::cin.get();
}
Run Code Online (Sandbox Code Playgroud)

主要功能运行平稳,没有任何警告或错误.这是为什么?如果头文件没有可以链接到的补充,那么如何编译呢?

Nik*_* C. 25

这一行:

Simpletron s();
Run Code Online (Sandbox Code Playgroud)

是一个函数原型,声明一个名为的函数s,返回一个Simpletron并且不带参数.它不会创建Simpletron名为的实例s.

现在您可能会问,为什么链接器不会抱怨不存在的s()函数呢?好吧,因为你只是声明s()但实际上从未实际调用它,所以在链接期间它实际上并没有被引用,因此你没有链接错误.


0x4*_*2D2 13

Simpletron s();
Run Code Online (Sandbox Code Playgroud)

这是函数声明,而不是对象实例化.空括号告诉编译器此函数不带参数,并返回一个Simpletron按值类型的对象,因此不会调用构造函数.正确的语法没有参数:

Simpletron s; // You will get an error on this line, as initially expected
Run Code Online (Sandbox Code Playgroud)

C++ 11增加了一个语法特性,避免了这种歧义:

Simpletron s{}; // same as default-initialization
Run Code Online (Sandbox Code Playgroud)

  • @MahanGM:"修复"意味着导致代码_按预期行为_. (4认同)

Mat*_*lia 5

    Simpletron s();
Run Code Online (Sandbox Code Playgroud)

这是"烦恼的解析"的经典案例; 对于编译器,您不是创建s类型的变量Simpletron,而是声明一个名为的函数s,不带参数并返回一个Simpletron对象.

这是因为这个表达式既可以解释为函数声明,也可以解释为变量声明; 因为声明变量有一个简单的替代方法(即,只是省略括号)标准要求将其解释为函数声明.

这在编译阶段没有问题(编译器不需要具有所有方法的定义,只需要声明),并且可能链接器没有给出任何错误,因为Simpletron实际上没有创建实例,因此它永远不需要实际上寻找构造函数定义(虽然我不认为它保证不会给出错误,但是一个特别彻底的编译器/链接器应该能够为缺少的构造函数提供错误).