混淆成员复制课程

时间:2011-09-15 23:12:38

标签: c++ assignment-operator

在用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;
}

所以,我没有得到概念。请提出其他示例(如果可能),以便我能更好地理解。

4 个答案:

答案 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,这意味着xv1本身的别名。 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!

这导致另外两个对象yz具有y.a == 15z.a == 15y.bz.b都是n。 (最后两个替代语法不要confused;都要调用复制构造函数。)