在用C ++研究成员复制和赋值运算符之后, 并查看“member copying of class”,它解释了无法生成默认赋值运算符的条件。我不太清楚这些概念,因为我尝试的以下示例实际上适用于g ++ 4.5
#include<iostream>
using namespace std;
class Y{
int& x;
const int cx;
public:
Y(int v1,int v2)
:x(v1),cx(v2)
{}
int getx(){return x;}
int getcx(){return cx;}
};
int main()
{
int a = 10;
Y y1(a,a);
Y y2 = y1;//assignment
cout<<y1.getx()<<" "<<y1.getcx();
return 0;
}
所以,我没有得到概念。请提出其他示例(如果可能),以便我能更好地理解。
答案 0 :(得分:2)
Y y2 = y1;
不是作业。这是一个复制构造函数调用。如果在同一行上声明并初始化变量,则会调用一个参数构造函数,并将等号的右侧作为参数。 Y
没有任何内容可以阻止默认的拷贝构造函数被实例化(并被调用)。
尝试以下方法:
Y y1(10, 10);
Y y2(11, 11);
y2 = y1;
这应该会失败,虽然我现在无法测试它。
答案 1 :(得分:1)
class Y{
int& x;
public:
Y(int v1,int v2)
:x(v1),cx(v2)
{} // v1 ceases to exist from this point
};
x
是int的引用变量。现在您将其初始化为v1
,这意味着x
是v1
本身的别名。 v1
的范围仅在构造函数中。随着说 -
Y y2 = y1;//assignment => Not assignment. It is initialization.
相当于
Y y2(y1); // compiler is looking for the overloaded constructor ( ie. copy constructor in this case ).
class Y{
public:
Y ( const Y & other ); // copy constructor
// ...
};
答案 2 :(得分:1)
#include<iostream>
using namespace std;
class Y{
int& x;
const int cx;
public:
Y(int v1,int v2)
:x(v1),cx(v2)
{}
int getx(){return x;}
int getcx(){return cx;}
};
int main()
{
int a = 10;
Y y1(a,a);
Y y2 = y1;//NOT assignment. Object is yet to be constructed, so calls copy c'tor
y2 = y1; // assignment operator is called
cout<<y1.getx()<<" "<<y1.getcx();
return 0;
}
/*
D:\Workspaces\CodeBlocks\Test\main.cpp||In member function 'Y& Y::operator=(const Y&)':|
D:\Workspaces\CodeBlocks\Test\main.cpp|4|error: non-static reference member 'int& Y::x', can't use default assignment operator|
D:\Workspaces\CodeBlocks\Test\main.cpp|4|error: non-static const member 'const int Y::cx', can't use default assignment operator|
D:\Workspaces\CodeBlocks\Test\main.cpp||In function 'int main()':|
D:\Workspaces\CodeBlocks\Test\main.cpp|20|note: synthesized method 'Y& Y::operator=(const Y&)' first required here |
||=== Build finished: 3 errors, 0 warnings ===|
*/
答案 3 :(得分:0)
您的类包含无法构造或分配的成员,即:
参考
常量
因此,您的类不能隐含默认构造函数或赋值运算符。例如,您必须编写自己的构造函数:
class Foo
{
const int a;
int & b;
public:
Foo(int val, int & modify_me) :
a(val) , // initialize the constant
b(modify_me) // bind the reference
{ }
};
很明显,你不能默认构造Foo
(即 )。很明显,您无法重新分配类Foo x;
Foo
的对象(即 ),因为您无法重新分配引用或常量。x = y;
通过为您的类提供引用或常量成员,您实际上会在类本身上赋予引用或常量语义,如果您愿意,那么这应该是一个相当直接的逻辑结果。例如,重新分配在语义上可能甚至没有意义,因为你的类应该体现一个不变的概念。
但是,请注意您可以制作班级的副本:这是因为您可以制作参考文献的“副本”(即更快的别名)和常量副本。因此,通过简单地应用copy-construction member-by成员,隐式地可以使用复制构造函数 。所以你可以说:
int n;
Foo x(15, n);
Foo y(x);
Foo z = x; // these two are identical!
这导致另外两个对象y
和z
具有y.a == 15
和z.a == 15
,y.b
和z.b
都是n
。 (最后两个替代语法不要confused;都要调用复制构造函数。)