如何修复不起作用的复制构造函数?[已结束]

How to fix a copy constructor that doesn't work? [closed]

提问人:Irimitlad 提问时间:8/12/2022 更新时间:8/12/2022 访问量:67

问:


这个问题是由一个错别字或一个无法再重现的问题引起的。虽然类似的问题可能在这里成为主题,但这个问题的解决方式不太可能帮助未来的读者。

去年关闭。

我正在尝试简化我的代码。为什么我不能使用带注释的构造函数而不是以前的(未注释的)构造函数?

struct Direction {
    const double x, y, z;
    Direction(double _X, double _Y, double _Z) : x(_X), y(_Y), z(_Z) {}
    Direction(Direction& _D) : x(_D.x), y(_D.y), z(_D.z) {}
}

class Movement {
private:
    const double v;
    const Direction d;
public:
    Movement(double _V, double _X, double _Y, double _Z) : v(_V), d(_X, _Y, _Z) {}
    Movement(double _V, Direction _D) : v(_V), d(_D) {}
    Movement(Movement& _M) : v(_M.v), d(_M.d.x, _M.d.y, _M.d.z) {} // this works
 // Movement(Movement& _M) : v(_M.v), d(_M.d) {}                   // this doesn't work
}

关于如何让它工作的任何想法?谢谢。

C++ 复制构造函数

评论

2赞 463035818_is_not_an_ai 8/12/2022
“doesn't work” 是什么意思?
0赞 paolo 8/12/2022
_M.d是 而 的 复制构造函数采用非 L 值引用。它如何编译?为什么 的复制构造函数采用非 l 值引用?为什么有私人会员?Direction constDirectionconstDirectionconstconst
1赞 AndersK 8/12/2022
也许不声明为 const 会有所帮助?d
0赞 Marek R 8/12/2022
错别字: godbolt.org/z/qq814jWGe - copy constructor needs .const
0赞 user12002570 8/12/2022
骗子1

答:

4赞 463035818_is_not_an_ai 8/12/2022 #1

错误消息相当清晰:

<source>: In copy constructor 'Movement::Movement(Movement&)':
<source>:15:44: error: binding reference of type 'Direction&' to 'const Direction' discards qualifiers
   15 |     Movement(Movement& _M) : v(_M.v), d(_M.d) {}                   // this doesn't work
      |                                         ~~~^
<source>:4:26: note:   initializing argument 1 of 'Direction::Direction(Direction&)'
    4 |     Direction(Direction& _D) : x(_D.x), y(_D.y), z(_D.z) {}
      |               ~~~~~~~~~~~^~

该成员是 ,但构造函数需要一个非常量引用。dconstDirection

如果构造函数采用常量引用,则代码将进行编译,因为构造函数不会修改参数:

struct Direction {
    const double x, y, z;
    Direction(double _X, double _Y, double _Z) : x(_X), y(_Y), z(_Z) {}
    Direction(const Direction& _D) : x(_D.x), y(_D.y), z(_D.z) {}
};

class Movement {
private:
    const double v;
    const Direction d;
public:
    Movement(double _V, double _X, double _Y, double _Z) : v(_V), d(_X, _Y, _Z) {}
    Movement(double _V, Direction _D) : v(_V), d(_D) {}
    //Movement(Movement& _M) : v(_M.v), d(_M.d.x, _M.d.y, _M.d.z) {} // this works
    Movement(Movement& _M) : v(_M.v), d(_M.d) {}                   // this doesn't work
};

int main() {
    Movement x(0.1,0.2,0.3,0.4);
    Movement y(x);
}

然而,成员是棘手的,很少是正确的方式。成员是私有的,因此即使在非常量上也没有必要制作它们。用户无论如何都无法修改它们。我建议从成员中删除所有参数,并添加到所有可以是 .特别是复制构造函数应将其参数为 .constconstMovementconstconstconstconst &

struct Direction {
    double x, y, z;
    Direction(double _X, double _Y, double _Z) : x(_X), y(_Y), z(_Z) {}
    Direction(const Direction& _D) : x(_D.x), y(_D.y), z(_D.z) {}
};

class Movement {
private:
    double v;
    Direction d;
public:
    Movement(double _V, double _X, double _Y, double _Z) : v(_V), d(_X, _Y, _Z) {}
    Movement(double _V, const Direction& _D) : v(_V), d(_D) {}
    Movement(const Movement& _M) : v(_M.v), d(_M.d) {}                   // this doesn't work
};

int main() {
    Movement x(0.1,0.2,0.3,0.4);
    Movement y(x);
}

如果 s 成员在构造后也不应修改,则使它们 .创建一个类成员足以防止其修改,而成员则阻止一些有用的操作(赋值等)。Directionprivateprivateconst