【问题标题】:Constructor generation构造函数生成
【发布时间】:2015-07-06 15:33:37
【问题描述】:

我有两个 C++ 结构,Rect 是浮点矩形,iRect 相同,但使用整数:

struct iRect {
    int X;
    int Y;
    int W;
    int H;
};

struct Rect {
    float X;
    float Y;
    float W;
    float H;
};

目前我可以使用 Rect{1.2, 2.4, 4.2, 0.2}; 语法构造这些。

现在我想让这些隐式转换,所以我为 Rect 创建一个新的构造函数:

Rect(iRect iR) {
    X = (float)iR.X;
    Y = (float)iR.Y;
    W = (float)iR.W;
    H = (float)iR.H;
}

我得到:error C2512: 'Rect' : no appropriate default constructor available 没什么大不了的,我只定义一个空的默认构造函数。

但现在我得到error C2440: 'initializing' : cannot convert from 'initializer-list' to 'Rect'

所以我必须为四个浮点数、三个浮点数、两个浮点数和一个浮点数定义另一个构造函数,以具有与以前相同的行为。这个例子也被简化了: Rect 实际上也是两个Vec2 类型的联合,所以我还必须为Rect (Vec2 a, Vec2 b) 定义一个构造函数。

通常所有这些构造函数都是由编译器生成的。我有什么方法可以定义我的 Rect(iRect iR) 构造函数而不阻止编译器生成所有其他构造函数?

【问题讨论】:

  • 你为什么不为此使用类?
  • 您可以使用转换函数 (operator Rect() const;),而不是转换构造函数。虽然我认为这是一个 xy 问题
  • This 可能会有所帮助。
  • Rect改成template<class T> class Rect {};可以减少很多重复代码。
  • @LawrenceAiello structclass,只是具有不同的默认成员访问权限。

标签: c++ constructor


【解决方案1】:

不用定义构造函数,而是定义一个转换运算符

struct iRect {
    ...
    operator Rect() const {
        return Rect{X,Y,W,H};
    }
};

每当 iRect 必须被隐式或显式转换为 Rect 时,转换运算符就会启动(可以添加 explicit 关键字以将其限制为仅显式转换)。定义了这个操作符,你现在可以写

iRect a;
Rect b = a;

如您所愿。

由于转换运算符不是构造函数,它们不会抑制默认构造函数 - 您的所有聚合初始化都将继续工作。

【讨论】:

  • 这似乎是我正在寻找的,虽然我会添加强制转换来停止编译器关于丢失数据的警告!我会尽快接受这个答案。
【解决方案2】:

使用转换函数。这种类型的设计在许多库中实现(想到 Qt)。此外,您的转换构造函数无缘无故地采用 iRect copy,您应该尽可能使用 C++ 样式转换。你可以简单地写:

Rect toRect(const iRect& i)
{
    Rect r;
    r.X = static_cast<float>(i.X);
    r.Y = static_cast<float>(i.Y);
    r.W = static_cast<float>(i.W);
    r.H = static_cast<float>(i.H);
    return r;
}

编辑:该死,@dyp 打败了我。

【讨论】:

【解决方案3】:

问题在于,如果没有构造函数,则存在默认聚合初始化器,请参阅here。在定义自定义构造函数时(我可能会说),聚合初始化不再可能。

正如其他人指出的那样,最好定义一个转换运算符

struct iRect {
    //...
    /* explicit */ operator Rect() const {
        return Rect{X,Y,W,H};
    }
};

explicit 可以添加,以便必须显式地进行转换,例如:

iRect r {1, 2, 3, 4};
Rect r2 = (Rect) r; // Explicit cast

【讨论】:

    猜你喜欢
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 2016-12-16
    • 2017-03-17
    • 2012-03-08
    • 2012-11-09
    • 2017-01-23
    • 2011-08-21
    相关资源
    最近更新 更多