很抱歉发布这样一个特定的问题,但我对大学里给出的一个示例问题感到困惑。问题是:
class BoundingBox {
private:
float m_width;
float m_height;
public:
BoundingBox(float width = 0, float height = 0) :
m_width(width), m_height(height) {}
};
class Enemy {
private:
EnemyType m_type;
BoundingBox m_box;
Enemy(BoundingBox const & box, EnemyType type = EnemyType::Boss) :
m_type(type);
m_box(box);
{}
};
问:Enemy
的以下结构是否合法?解释
Enemy enemy1(10);
提供的答案是,因为10是作为width
参数传入的,默认值用于height
,默认值用于EnemyType
}。但根据我的理解,行:
BoundingBox const & box
期望将box
对象传递给它,而不是它的构造函数的参数。
我的讲师犯了错误,还是我错过了什么?如果我误解了,你能不能给我提供一个链接来解释“引擎盖下”发生的事情。我不知道这是构造对象的有效方法。我会问我的讲师,但他已经病了一个星期,我在网上找不到任何关于基于参数的建设。
答案 0 :(得分:3)
是的,它很好并且将编译(禁止语法和对构造函数的访问)。
要创建Enemy
类型,需要BoundingBox
;特别是Enemy
构造函数接受参数为const&
,从而允许使用临时值。
要创建BoundingBox
,不能使用任何参数,可以使用一个float
或两个float
。变化是因为BoundingBox
构造函数中提供了默认参数。构造函数没有标记为explicit
(这是使其工作的关键位),因此编译器可以自己implicitly create临时BoundingBox
- 它适当地做,然后创建Enemy
对象。
添加explicit
将导致编译失败;这样做是有建设性的,并观察您收到的错误消息。我怀疑这可能是未来讲座的主题。
一般而言,通常会给出标记构造函数的建议,这些构造函数可以将单个参数(考虑默认值)设置为explicit
,从而防止未知(或看不见)的转换。如果需要隐式转换,则不要添加explicit
。
清除了语法问题的代码;
class BoundingBox {
private:
float m_width;
float m_height;
public:
/*explicit*/ BoundingBox(float width = 0, float height = 0) :
// ^^^^^^^ experiment with and without this being present
m_width(width), m_height(height) {}
};
class Enemy {
private:
EnemyType m_type;
BoundingBox m_box;
public:
// ^^^ added to allow access to the constructor
Enemy(BoundingBox const & box, EnemyType type = EnemyType::Boss) :
m_type(type),
// ^ syntax here
m_box(box)
// ^ syntax here
{}
};