C++对象实例化 - 当使用空括号实例化一个对象时,调用哪个构造函数 [重复] 。

问题描述 投票:0回答:2

我对实例化对象的不同语法感到困惑。

这是我的类。

class Object
{

private:

    int field = 0;

public:

    Object() = default; // Just for testing.
    ~Object() = default; // Just for testing.

    Object( const Object& obj ) = default; // Just for testing.

};

这是主方法:

int main()
{
    Object b(); // ???
    Object c{}; // default
    Object d = Object(); // default
    Object e = Object{}; // default
    Object f ( Object() ); // ???
    Object g { Object() }; // default
    Object a; // default but avoid
    Object h ( Object() ); // ???
    Object i { Object{} }; // default
    Object j = i; // copy
    Object k( j ); // copy
    Object l{ k }; // copy
    Object m = { l }; // copy
    Object n = ( m ); // copy
    auto o = Object(); // default
    auto p = Object{}; // default
    return 0;
}

我对标明的那个方法没有问题 defaultcopy. 我只是想知道,哪个构造函数被调用为一个有 ??? 因为默认的那个没有被调用。这是否与 () 初始化,可见一斑。

我知道这可能并不重要,但我对此很怀疑。

谁能帮帮我!?

c++ initialization instantiation
2个回答
2
投票

这三个声明都是函数声明,但不是变量定义(如你所料)。

Object b(); 声明了一个名为 b,它不需要任何东西,并返回 Object.

Object f ( Object() ); 声明一个名为 f,它接受一个未命名的参数,该参数的类型是一个函数,返回的是 Object 而什么也不取(即 Object()),并返回 Object. 同样,对于 Object h ( Object() );.

作为变通办法,对于 Object b(); 你可以

Object b;
Object b{}; // since C++11

对于 Object f ( Object() ); 你可以

Object f ( ( Object() ) );
Object f ( Object{} );     // since C++11
Object f { Object{} };     // since C++11
Object f { Object() };     // since C++11

请看 最麻烦的解析 更多。


2
投票

它实际上没有调用任何构造函数。

当你改变Object类,使所有的字段都是公共的(所以你可以查看它们)。

#include <iostream>
class Object
{
public:
    int field = 0;
    Object() = default;
    ~Object() = default;
    Object( const Object& obj ) = default;
};

然后你试图调用主方法中的空括号:

int main()
{
    Object b();
    std::cout << b.field << '\n';
    return 0;
}

你会得到一个错误,因为 b 不是一个对象,而是一个函数。

错误:请求在'b'中使用成员'field',它是非类类型'Object()'。

这就是为什么,当你要调用空括号构造函数时,你必须调用没有任何括号的构造函数。

int main()
{
    Object b;    // this is correct
    std::cout << b.field << '\n';
    return 0;
}

1
投票

你正确识别了所有的构造函数 你不确定的三个构造函数并不像你想象的那样。

Object b();
Object f ( Object() );
Object h ( Object() );

所有这些构造函数都是 功能声明,而不是变量定义。

你声明一个函数 b 没有参数,并返回一个 Object. 然后你声明两个函数。fh,有一个未命名的参数,并返回一个 Object. 参数的类型是:无参数的函数,返回的是 Object.

这就是所谓的 最麻烦的解析. 基本上C++标准是这样说的:"如果它可以被解析为函数声明,就必须被解析为函数声明"。Clang甚至对此有警告。-Wvexing-parse.

© www.soinside.com 2019 - 2024. All rights reserved.