为什么此C ++构造函数会自动定向到副本构造函数?

时间:2018-10-20 21:36:54

标签: c++

我得到了

Docker Version:
PS C:\> docker version
Client:
Version:           18.03.1-ee-3  
API version:       1.37
Go version:        go1.10.2
Git commit:        b9a5c95
Built:             Thu Aug 30 18:42:35 2018
OS/Arch:           windows/amd64
Experimental:      false

Server:
Engine:
Version:          18.03.1-ee-3
API version:      1.37 (minimum version 1.24)
Go version:       go1.10.2
Git commit:       b9a5c95
Built:            Thu Aug 30 18:56:49 2018
OS/Arch:          windows/amd64
Experimental:     true

在调用行出现错误(因为我的课程中没有复制构造函数)

Severity    Code    Description    Project    File    Line    Suppression State
Error    C2280    'World::World(const World &)': attempting to reference a
deleted function

这是一个构造函数。

我对为什么将副本构造函数自动定向感到非常困惑。

有人有什么主意吗?

这是我的班级头文件:

World wd = World(&vp, am);

还有我的构造函数:

class World{
    public:
        KDtree tree;
        ViewPlane *vp;
        DrawPanel * paintArea = &(DrawPanel(wxString("test"), wxDefaultPosition, 400,400));
        wxApp app;
        Vector3d backGround;
        vector <Geometry*> objects;
        Shader shader;
        vector<Light*>lights;

        World(ViewPlane*, Vector3d& Am);
        ....
}

4 个答案:

答案 0 :(得分:4)

使用

Bar b = Bar(...)

语法实际上确实进行了复制初始化:https://en.cppreference.com/w/cpp/language/copy_initialization

您可能只想

World wd(&vp, am);

相反。

答案 1 :(得分:4)

除了其他答案外,我想指出的是,由于C ++ 17由于保证了复制省略,因此T()之类的表达式中不涉及来自临时对象T t = T()的副本。不需要现有的可访问副本构造函数。

答案 2 :(得分:0)

直到C ++ 17

World wd = World(&vp, am);

被解释为“使用表达式World构造World(&vp, am)对象,然后使用该对象复制构造局部变量World wd。大多数编译器会跳过复制步骤,但仍然该标准要求它不会调用它们的副本构造函数。

在C ++ 17中,要求编译器取消副本,因此即使没有副本构造函数,也能够编译此代码片段。 因此,您可以选择使用C ++ 17或使用语法

World wd{&vp, am};

(用括号代替大括号也可以。)

答案 3 :(得分:-10)

使用:

World *wd = World(&vp, am);

上面的语句执行以下操作:

  1. 使用简单的构造函数为World创建类型为World的对象 世界。
  2. 使用构造函数创建World类型的对象 世界(const World&)。
  3. 在步骤1中创建的对象上调用〜World()。

所以最好的方法是使用:

World wd(&vp, am);

实质上是通过调用World类的简单构造函数在堆栈上创建一个新对象。

另一种(麻烦的)方法可以使用 new运算符

World *wd = new World(&vp, am);