如果我有这些课程:
class A
{
int x,y;
public:
A(const int &x,const int &y):x(x),y(y){}
};
class B:public A
{
int z;
public :
B(const int &x,const int &y,const int &thez):z(thez),A(x+z,y+z)
};
我想在调用A的构造函数之前初始化类B中的z
,但是正如我从调试A中发现的那样构造函数始终被调用,无论它放在何处。
这个的真正目标是计算由三个立方体(头部,身体和腿部)组成的Player类(在foosball中找到的Player)的旋转惯性,三个立方体在Player构造函数和Player中初始化惯性在Body的构造函数中初始化(Body是Player的父级)。
我的问题是播放器的惯性取决于立方体的惯性,我计算它们并且我想对它们求和并在其上调用父节点但是我不能在不初始化立方体的情况下对它们求和(它们之前没什么初始化)。
那怎么办呢?
我知道我可以把关系和总和放在一起,是的,但是这很长,如果我这样做,构造函数会很容易变得丑陋,我认为这只是最后的选择。
答案 0 :(得分:2)
除了这样做是否是一个好主意之外:如果你想在基类成员之前初始化派生类成员,你可以使用base-from-member-idiom:只需将相应的成员放入另一个基础中class并确保它首先被初始化。
class A
{
int x,y;
public:
A(const int &x,const int &y):x(x),y(y) {}
};
class Z
{
int z;
Z(const int &thez): z(thez) {}
};
class B: public Z, public A
// ^^^^^^^^
// Z must come before A
{
public :
B(const int &x,const int &y,const int &thez): Z(thez), A(x+z,y+z) {}
};
这个基类Z
- 特别是其成员z
- 将在A
的成员之前进行初始化。
免责声明:一般情况下,请注意多重继承及其diamond of death。
答案 1 :(得分:0)
如果你没有修改" z"在将它传递给父类之前,你应该通过" z"像这样的父类:
Sub Clear_FM_Contents()
Dim f As FileDialog
Dim varfile As Variant
Dim path As Variant
'Prompt the user to select the Excel File to Import
Set f = Application.FileDialog(msoFileDialogFilePicker)
'Error handling with file selector
If f.Show = False Then
MsgBox "You clicked Cancel in the file dialog box."
End
End If
'Set the path of the User selected file
For Each varfile In f.SelectedItems
path = varfile
Next
'Create the Excel object
Dim xlApp As Excel.Application
Set xlApp = CreateObject("Excel.Application")
xlApp.Visible = True
'Open the selected Excel file
xlApp.Workbooks.Open path, True, False
'Clear all Template Inputs
With xlApp.ActiveWorkbook
.Sheets("Mrkt Data").Select
With xlApp.ActiveWorkbook.ActiveSheet
.Range("E36,E5,E7,E10,E13,E17,E39,J7:J11,J13:J20,J24:J29,J31:J33,J35,O21").Select
.Range("O21").Activate
xlApp.ActiveWorkbook.ActiveSheet.Selection.ClearContents
End With
'Close the Excel File
ActiveWorkbook.Save
ActiveWorkbook.Close
End With
'Close Excel
xlApp.Quit
'Eliminate the xl app object from memory
Set xlApp = Nothing
MsgBox "Model Inputs Cleared"
End Sub
这样父类就会获得" z"增值到它的" x"和" y"你还可以存储" z"的价值。供以后使用。
另一种方法是使用派生类构造函数来修改继承的值,如下所示:
class B:public A
{
int z;
public :
B(const int &x,const int &y,const int &thez):A(x+thez,y+thez), z(thez)
};
这仅适用于您未在父构造函数中进行其他修改的情况。
答案 2 :(得分:0)
其他答案已就如何解决您的问题提出了一些建议 - 我的建议是稍微区别地思考问题。
这似乎是using composition instead of inheritance可能是个好主意的情况。
在你的情况下,你说“身体”是“玩家”的父母,这让我认为这可能是一个可以重新考虑的设计选择。我会考虑这样想:
这个类层次结构反映了Player和BodyPart之间的关系不是“是一个”关系的事实,它是一个“有一个”(或“有一些”)的关系。虽然他们可能共享一个用于访问惯性的通用API,但他们实现它的方式却不同,因为它们代表了根本不同的东西。
虽然这并没有解决您在调用父构造函数之前询问如何初始化成员变量的特定编程问题,但我认为值得一提的是,如果其他人因为做出类似的设计选择而找到了这个问题引导他们到这一点。