与类的成员复制混淆
Confusion with member copying of class
在学习了c++中的成员复制和赋值操作符之后,看看"类的成员复制",它解释了不能生成默认赋值操作符的条件。我不是很清楚的概念,因为下面的例子我尝试实际工作在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;
}
那么我哪里没有得到概念。
Y y2 = y1;
不是赋值。这是一个复制构造函数调用。如果在同一行声明和初始化一个变量,则调用一个单参数构造函数,并将等号的右侧作为参数。Y
没有阻止默认复制构造函数被实例化(和调用)。
尝试以下操作:
Y y1(10, 10);
Y y2(11, 11);
y2 = y1;
这应该失败,虽然我现在不能测试它
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
// ...
};
#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:WorkspacesCodeBlocksTestmain.cpp||In member function 'Y& Y::operator=(const Y&)':|
D:WorkspacesCodeBlocksTestmain.cpp|4|error: non-static reference member 'int& Y::x', can't use default assignment operator|
D:WorkspacesCodeBlocksTestmain.cpp|4|error: non-static const member 'const int Y::cx', can't use default assignment operator|
D:WorkspacesCodeBlocksTestmain.cpp||In function 'int main()':|
D:WorkspacesCodeBlocksTestmain.cpp|20|note: synthesized method 'Y& Y::operator=(const Y&)' first required here |
||=== Build finished: 3 errors, 0 warnings ===|
*/
您的类包含不能默认构造或赋值的成员,即:
- 引用
- 常量
因此,不能为类隐含默认构造函数或赋值操作符。例如,您必须编写自己的构造函数:
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;
通过为类提供引用或常量成员,实际上是在类本身上授予引用或常量语义,如果您愿意的话,因此这应该是一个相当直接的逻辑结果。例如,重赋值甚至可能在语义上没有意义,因为你的类应该包含一个常量概念。
但是,请注意,可以创建类的副本:这是因为您可以创建引用的"副本"(即进一步别名)和常量的副本。因此,只需逐个成员应用复制构造函数,就可以隐式地使用复制构造函数。所以你可以说: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
的引用。(不要被结尾的两种语法所迷惑;都调用复制构造函数)
相关文章:
- 是否可以初始化不可复制类型的成员变量(或基类)
- 为什么类中的ostringstream类型的成员会导致";调用隐含删除复制构造函数";错误
- 访问类成员而不复制此变量或互斥变量
- std::ofstream 作为类成员删除复制构造函数?
- 正在复制具有未初始化成员的结构
- 直接初始化不可复制、不可移动的成员,而不使用聚合初始化
- 具有 STL 向量类型成员的类的复制内存
- 是否可以将不可复制的成员用作使对象不可复制的替代方法?
- 将C++浮点数组成员直接封送到 C#,而无需复制
- 在临时将成员带出时省略复制/移动
- 复制赋值函数如何访问另一个对象的私有成员(Stroustroup 原则和实践书)?
- C++ 阻止复制成员数据
- C++列表:复制成员列表中的本地列表
- 使用模板类复制成员函数
- 即使复制构造函数由于 RVO 在C++中未被调用,如何复制成员变量的值
- 具有不可复制成员的类的聚合初始化
- 请参阅 TC++PL 第 3 版的第 10.4.6.3 节"复制成员"
- 初始化不可复制成员
- 关于包含不可复制成员引用的类的复制构造函数的建议
- 错误到底是什么,对于错误地调用可移动和不可复制成员的复制构造函数有什么解决方法