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

时间:2013-09-24 00:32:08

标签: c++

我有Simpletron.cpp这是文件,Simpletron.h声明了Simpletron类:

class Simpletron 
{    
public:
    Simpletron();
};

我在main.cpp中调用了Simpletron()

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

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

    Simpletron s();
    std::cin.get();
}

主要功能运行顺畅,没有任何警告或错误。这是为什么?如果没有头文件可以链接到的实现,那么如何编译甚至编译?

3 个答案:

答案 0 :(得分:25)

这一行:

Simpletron s();

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

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

答案 1 :(得分:13)

Simpletron s();

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

Simpletron s; // You will get an error on this line, as initially expected

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

Simpletron s{}; // same as default-initialization

答案 2 :(得分:5)

    Simpletron s();

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

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

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