1

After studying the member copying and the assignment operator in C++, and looking at " member copying of class " which explains the conditions where default assignment operator cannot be generated. I am not very clear about the concepts as the following example I tried actually works on 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;
}

So where am I not getting the concepts. Please suggest other examples (if possible) so that I can understand better.

Community
  • 1
  • 1
A. K.
  • 34,395
  • 15
  • 52
  • 89

4 Answers4

2

Y y2 = y1; is not an assignment. It's a copy constructor call. If you declare and initialize a variable on the same line, a one parameter constructor is called with the right hand side of the equals sign as the parameter. There's nothing about Y that prevents the default copy constructor from being instantiated (and called).

Try the following:

Y y1(10, 10);
Y y2(11, 11);
y2 = y1;

This should fail, although I can't test it right now.

Oscar Korz
  • 2,457
  • 1
  • 18
  • 18
1
class Y{
  int& x;

  public:
  Y(int v1,int v2)
    :x(v1),cx(v2)
  {} // v1 ceases to exist from this point
};

x is a reference variable to an int. Now you are initializing it to v1, which means x is an alias to v1 itself. The scope of v1 is in the constructor alone. With that said -

 Y y2 = y1;//assignment => Not assignment. It is initialization.

is equivalent to

 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
       // ...
 };
Mahesh
  • 34,573
  • 20
  • 89
  • 115
  • yes you are right, but the program works as is. i mean why there is no error message even i am wondering. after the constructor returns what is stored in `x`? – A. K. Sep 15 '11 at 23:26
  • @Aditya Kumar - Yeah, I see my self of it compiled on gcc (http://ideone.com/RZxKC). Let's wait and see if any one is going to correct us. – Mahesh Sep 15 '11 at 23:27
  • This is incorrect. The compiler will provide an assignment operator and a copy constructor as long as none exists. The existence of user-defined constructors does not affect this behavior. – Oscar Korz Sep 16 '11 at 02:45
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 ===|
*/
Kashyap
  • 15,354
  • 13
  • 64
  • 103
0

Your class contains members which cannot be default-constructed or assigned, namely:

  • References

  • Constants

Therefore, no default constructor or assignment operator can be implied for your class. For example, you have to write your own constructor:

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
  { }
};

It is clear that you cannot default-construct Foo (i.e. Foo x;). It is also clear that you cannot reassign objects of class Foo (i.e. x = y;), because you cannot reassign references or constants.

By giving your class a reference or a constant member, you actually confer reference or constant semantics on the class itself, if you will, so this should be a fairly immediate logical consequence. For example, reassignment probably doesn't even make sense semantically, because your class is supposed to embody a constant concept.

However, note that you can make copies of your class: That's because you can make "copies" of references (i.e. furhter aliases), and copies of constants. Therefore, a copy constructor is available implicitly, by simply applying copy-construction member-by member. So you can say:

int n;
Foo x(15, n);

Foo y(x);
Foo z = x;  // these two are identical!

This results in two further objects y and z which have y.a == 15 and z.a == 15, and y.b and z.b are all references to n. (Don't be confused by the two alternative syntaxes at the end; both invoke the copy constructor.)

Community
  • 1
  • 1
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084