如果每个作业都创建了一个临时文件,将对象复制到左值,那么如何在VC ++ 8.0中查看?
class E
{
int i, j;
public:
E():i(0), j(0){}
E(int I, int J):i(I), j(J){}
};
int main()
{
E a;
E b(1, 2);
a = b //would there be created two copies of b?
}
修改
Case 2:
class A
{
int i, j;
public:
A():i(0), j(0){}
};
class E
{
int i, j;
A a;
public:
E():i(0), j(0){}
E(int I, int J):i(I), j(J){}
E(const E &temp)
{
a = temp; //temporary copy made?
}
};
int main()
{
E a;
E b(1, 2);
a = b //would there be created two copies of b?
}
答案 0 :(得分:1)
根据您的评论,您明确表示您不太了解this C++-FAQ item。
首先,您提供的代码中没有临时值。声明A::operator=
的编译器被调用,您只需1
中的a.i
和2
中的a.j
。
现在,关于您提供的链接,它仅与构造函数有关。在以下代码中:
class A
{
public:
A()
{
s = "foo";
}
private:
std::string s;
};
数据成员s
是使用std::string
无参数构造函数构建的,然后在"foo"
构造函数体中分配了值A
。在初始化列表中初始化数据成员(与i
和j
一样),最好(事实上,必要)在初始化列表中初始化:
A() : s("foo")
{
}
这里,s
数据成员在一步中初始化:通过调用适当的构造函数。
答案 1 :(得分:0)
如果您不提供,可以自动为您创建一些标准方法。如果你写
struct Foo
{
int i, j;
Foo(int i, int j) : i(i), j(j) {}
};
编译器将其完成为
struct Foo
{
int i, j;
Foo(int i, int j) : i(i), j(j)
{
}
Foo(const Foo& other) : i(other.i), j(other.j)
{
}
Foo& operator=(const Foo& other)
{
i = other.i; j = other.j;
return *this;
}
};
换句话说,您通常会获得一个复制构造函数和一个基于成员的赋值运算符。具体而言,赋值运算符不构建任何临时对象。
理解这些隐式定义的方法是如何工作的非常重要,因为大多数时候它们确实是你需要的正确的东西,但有时候它们是完全错误的(例如,如果你的成员通常是指针的成员)成员复制或分配不是处理操作的正确方法。)
答案 2 :(得分:0)
这会创建一个临时的:
E makeE( int i, int j )
{
return E(i, j);
}
int main()
{
E a;
a = makeE( 1, 2 );
E b = makeE( 3, 4 );
}
makeE返回一个临时的。 a被分配给临时,并且总是在此处调用赋值运算符。 b不是“赋值”,因为它在这里被初始化,并且需要一个可访问的拷贝构造函数才能工作,尽管不能保证拷贝构造函数实际上会被调用,因为编译器可能会优化它。