在工作的时候,我遇到了一段奇怪/令人困惑的代码,我觉得这些代码与匿名 对象生命周期概念有关。下面是代码示例:
#include<iostream>
#include<string>
class A {
private:
int i;
std::string s;
public:
A(int ii, std::string ss = "Hello") { i = ii; s = ss; }
void Display() { std::cout<<i<<"\n"; }
~A() { std::cout<<"A::~A()"<<"\n";}
};
void function()
{
A a = 1;
//A a = A(1);
a.Display();
}
int main()
{
function();
return 0;
}
VS2010中的输出1(如果A a = 1)
1
A::~A()
VS2010中的输出2(如果A a = A(1))
A::~A()
1
A::~A()
output2 非常有意义,因为析构函数被调用两次(包括匿名)对象。
然而 output1 让我感到困惑,无法理解为什么析构函数被调用一次(不是匿名)对象。
A a = 1;
上面的行将调用类A(const A& rhs)
的复制构造函数(A
),并且编译器应使用参数1
创建匿名对象。如果是这种情况,析构函数应该被调用两次。
有人可以解释一下这种行为吗?可能是我错过了一些明显的东西。
答案 0 :(得分:8)
A a = A(1);
相当于A a = 1;
。但是,在这两种情况下,都可能出现copy elision:A(1)
实际上直接构建到a
,而不是单独构建,然后复制或移动。
由编译器决定是否在其允许的任何场景中执行复制省略(如上面的链接所述)。
答案 1 :(得分:3)
您的编译器正在删除Public Sub SaveRaidDetails()
lblStatus.Text = ""
Dim dt2 As DataTable = CType(ViewState("dt1"), DataTable)
Dim er As Boolean = False
Dim dtRaidDate As Date
If dt2.Rows.Count > 0 Then
Try
dtRaidDate = Convert.ToDateTime(txtRaidDate.Text)
Catch ex As Exception
er = True
End Try
If er = False Then
lblDateEr.Visible = False
Dim intDisID, intMktSeq, intAgID As Integer
Dim dblFine As Double
If ddlDistributor.SelectedValue = "" Then
intDisID = 0
Else
intDisID = ddlDistributor.SelectedValue
End If
If ddlMarkets.SelectedValue = "" Then
intMktSeq = 0
Else
intMktSeq = ddlMarkets.SelectedValue
End If
If ddlAgency.SelectedValue = "" Then
intAgID = 0
Else
intAgID = ddlAgency.SelectedValue
End If
If txtFine.Text = "" Then
dblFine = 0
Else
dblFine = Convert.ToDouble((txtFine.Text))
End If
Dim intUserSeq As Integer = Convert.ToInt32(Session("UserSeq"))
Dim ret As Boolean
Dim rd1 As New RIMS_DATA.Raids
ret = rd1.AddRaid(dtRaidDate, txtCo.Text, txtCa.Text, intDisID, Convert.ToInt32(ddlRegion.SelectedValue), intAgID, intMktSeq, txtTrader.Text, txtTraderAdd.Text, dblFine, txtRemarks.Text, intUserSeq)
If ret = True Then
Dim intRaidID As Integer = rd1.ReadLastRaid()
Dim dtBatchDt As Date
For Each dr As DataRow In dt2.Rows
Try
dtBatchDt = Convert.ToDateTime(dr("BDt"))
Catch ex As Exception
dtBatchDt = Convert.ToDateTime("01/01/2000")
End Try
ret = rd1.AddRaid2(intRaidID, Convert.ToInt32(dr("BID")), Convert.ToInt32(dr("Qty")), dr("BCd"), dtBatchDt)
Next
ClearForm(1)
lblStatus.Text = "Record inserted successfully !"
lblDateEr.Visible = True
End If
End If
End If
Else
lblStatus.Text = "Please enter the raid details !"
End If
的副本,但不会删除A a = 1
的副本,gcc在这两种情况下都可以elide副本,可以使用A a = A(1);
进行测试