我教C ++,我需要一个好的,简单的日常例子,当你使用它时:
SELECT
USERINFO.Name,
USERINFO.SSN,
USERINFO.Badgenumber,
FORMAT(CHECKINOUT.CHECKTIME, "AMPM") AS [AM/PM],
FORMAT((Min(CHECKINOUT.CHECKTIME)),"dd-mmm-yyyy hh:mm am/pm") AS TIMEIN,
FORMAT((Max(CHECKINOUT.CHECKTIME)),"dd-mmm-yyyy hh:mm am/pm") AS TIMEOUT
FROM
CHECKINOUT
INNER JOIN
USERINFO ON CHECKINOUT.USERID = USERINFO.USERID
WHERE
(CHECKINOUT.CHECKTIME >= DATEVALUE(PERIOD_START) AND
CHECKINOUT.CHECKTIME < DATEADD("d", 1, PERIOD_END) AND
USERINFO.Name = Insert_Name
GROUP BY
CHECKINOUT.USERID,
USERINFO.Name,
USERINFO.SSN,
DateValue(CHECKINOUT.CHECKTIME),
FORMAT(CHECKINOUT.CHECKTIME, "AMPM"),
USERINFO.Badgenumber
HAVING
(((USERINFO.Badgenumber) < "8000"))
ORDER BY
USERINFO.Name,
FORMAT(CHECKINOUT.CHECKTIME, "AMPM"),
Min(CHECKINOUT.CHECKTIME);
这里D继承了两次,因为没有涉及虚拟继承。
我需要一个易于理解的动机示例,说明何时需要此构造。我甚至不需要代码;我只需要能够向我的学生展示一个例子,他们就会惊呼,#34;是的,我可以看到那将是有用的!&#34;
答案 0 :(得分:2)
简短版本:钻石配置中的多个非虚拟继承 从不 有用。
更长的版本: 您在此处描述的情况称为the diamond problem。这正是虚拟继承旨在解决的情况。
我理解你对你的问题的意思,如果语言中存在某种东西,那肯定是因为某些原因。它至少对于非常狭窄的情况很有用。但我宁愿以这种方式看待情况:
答案 1 :(得分:1)
我建议这个例子用于虚拟和非虚拟多重继承:
A - &gt;人(身份证,姓名)
B - &gt;老师(薪水)
C - &gt;学生(商标)
D - &gt; AssitantTeacher
对我来说,助理教师是一名刚毕业的老师,正在教授和准备更高学位(硕士或博士)。他有薪水和分数。
要添加非虚拟风味,假设教师具有特定格式的ID,并且学生具有其他格式的ID。 AssistantTeacher有两个ID:一个教师ID(用作HR数据库中的主键)和一个学生ID(用作学术系统数据库中的PK)。
[编辑]
例如,HR ERP系统会给教师一个自动增量ID,学生系统会给学生提供以下格式:YYYYMMSAAAA(其中Y是学生的入学年份,M是月,S是性别:0或1,A是自动增量id部分)。
助理教师的人力资源系统ID为“1332”,学生编号为“20170100004”。
答案 2 :(得分:1)
这不是一个简单的问题,因为任何关于它的讨论都将导致继承与构成。
有关虚拟继承的示例,我将保留您的国际象棋示例
Chess_piece
attributes: pos_x, pos_y;
/ \
_________________/ \___________________
/ \
Bishop Rook
methods: methods:
first_diagonal_move(length) horizontal_move(length)
second_diagonal_move(length) vertical_move(length)
\__________________ ___________________/
\ /
Queen
女王继承了Rook和Bishop的方法,但女王只有一个单一的属性,所以我们将在这里使用C ++虚拟继承。
接下来想象我们构建一个由一个圆和一个点组成的复合几何图形。这是一个&#34;继承&#34;图:
Point Point
attributes: pos_x, posy attributes: pos_x
| |
| |
Circle |
attribute: radius |
\___________ ________________/
\ /
Figure
这里的图将有两个不同的Point实例,因此我们不会使用虚拟继承。
事实上,这是因为在第二种情况下,我们尝试使用继承,其中正确的模式应该是合成:图形实际上包含一个点和圆。这种非虚拟继承会导致复杂的问题,例如图的位置是什么?。因此,OO建议使用composition over inheritance规则。
但是正如上面链接页面中详细讨论的那样,继承有技术好东西:派生类可以立即访问其基类方法,而在组合模式中,你必须明确地实现他们甚至建立一个简单的转发实现。在某些情况下,它会导致很多沸腾的拼盘代码,代码越多,测试成本就越高(如果不这样做,则会出现更多的错误风险......)
TL / DR:多重继承本身就是一种复杂的模式,在某些后C ++语言(例如Java)中不允许这样做。非虚拟多重继承通常是模式气味的暗示,因为在组合应该具有的情况下使用继承。但如果您知道为什么使用它(避免代码重复 是可接受的原因)并且您记录它,则可以使用它。毕竟C ++语言允许它......
答案 3 :(得分:0)
在C ++中,继承并不总是意味着子类型,至少是可访问的子类型:继承关系具有访问控制,就像成员访问一样。
非虚拟继承是继承的排他关系。虚拟继承是可以共享的继承关系。
非虚拟继承是对象与其直接基类之间的严格关系,例如,成员资格是对象与其成员之间的严格关系。虚拟继承是一种松散的关系;在某种程度上,虚拟继承绝不是间接的。每个构造函数初始化直接基础和成员,并且信息以递归方式传递给基础子对象和最内层成员的构造者;但最派生对象的构造函数直接初始化虚拟基类。
继承允许派生类覆盖虚函数。因为虚拟继承是一种共享关系,所以覆盖基类虚函数的责任在几个“兄弟”类之间共享;这些兄弟姐妹必须合作如何覆盖(共享)基类的(共享)虚函数。
您应该在以下情况下使用非虚拟继承: