tags:

views:

491

answers:

7

lets put a simple example:

struct some_struct {
   std::string str;
   int a, b, c;
}

some_struct abc, abc_copy;
abc.str = "some text";
abc.a = 1;
abc.b = 2;
abc.c = 3;

abc_copy = abc;

then abc_copy is an exact copy of abc.. how is it possible without defining the = operator?

(this took me by surprise when working on some code..)

+2  A: 

The compiler will synthesise some members for you if you don't define them explicitly yourself. The assignment operator is one of them. A copy constructor is another, and you get a destructor too. You also get a default constructor if you don't provide any constructors of your own. Beyond that I'm not sure what else but I believe there may be others (the link in the answer given by 280Z28 suggests otherwise though and I can't remember where I read it now so maybe it's only four).

Troubadour
A: 

structs are basically a concatenation of its components in memory (with some possible padding built in for alignment). When you assign one struct the value of another, the values are just coped over.

Scott M.
+2  A: 

But it is defined. In the standard. If you supply no operator =, one is supplied to you. And the default operator just copies each of the member variables. And how does it know which way to copy each member? it calls their operator = (which, if not defined, is supplied by default...).

eran
+3  A: 

That behavior is necessary in order to maintain source compatibility with C.

C does not give you the ability to define/override operators, so structs are normally copied with the = operator.

Ferruccio
ephemient
Ferruccio
+3  A: 

The assignment operator (operator=) is one of the implicitly generated functions for a struct or class in C++.

Here is a reference describing the 4 implicitly generated members:
http://www.cs.ucf.edu/~leavens/larchc++manual/lcpp_136.html

In short, the implicitly generated member performs a memberwise shallow copy. Here is the long version from the linked page:

The implicitly-generated assignment operator specification, when needed, is the following. The specification says that the result is the object being assigned (self), and that the value of the abstract value of self in the post-state self" is the same as the value of the abstract value of the argument from.

// @(#)$Id: default_assignment_op.lh,v 1.3 1998/08/27 22:42:13 leavens Exp $
#include "default_interfaces.lh"

T& T::operator = (const T& from) throw();
//@ behavior {
//@   requires assigned(from, any) /\ assigned(from\any, any);
//@   modifies self;
//@   ensures result = self /\ self" = from\any\any;
//@   ensures redundantly assigned(self, post) /\ assigned(self', post);
//           thus
//@   ensures redundantly assigned(result, post) /\ assigned(result', post);
//@ }
280Z28
Is that empty exception specification correct?
Rob Kennedy
The default assignment operator can't throw because it doesn't allocate any memory. :dunno:
280Z28
Steve Jessop
+5  A: 

In C++, structs are equivalent to classes where members default to public rather than private access.

C++ compilers will also generate the following special members of a class automatically if they are not provided:

  • Default constructor - no arguments, default initalizes everything.
  • Copy constructor - ie a method with the same name as the class, that takes a reference to another object of the same class. Copies all values across.
  • Destructor - Called when the object is destroyed. By default does nothing.
  • Assignment operator - Called when one struct/class is assigned to another. This is the automatically generated method that's being called in the above case.
MHarris
An implicit default constructor is also not provided if there is *any* user-defined constructor.
sellibitze
An implicit destructor also invokes destructors of members and subobjects (if there are any)
sellibitze
+1  A: 

If you do not define these four methods the compiler will generate them for you:

If you define a class like this:

struct some_struct: public some_base
{   
    std::string str;
    int a;
    int b;
    int c;
}

What the compiler will build is:

struct some_struct: public some_base
{   
    std::string str;
    int a;
    int b;
    int c;

    some_struct()
        :some_base()
        // PODS not initialised
        ,str()
    {}

    some_struct(some_struct const& copy)
        :some_base(copy)
        ,str(copy.str)
        ,a(copy.a)
        ,b(copy.b)
        ,c(copy.c)
    {}

    some_struct& operator=(some_struct const& copy)
    {
        some_base::operator=(copy);
        str  = copy.str;
        a    = copy.a;
        b    = copy.b;
        c    = copy.c;
        return *this;
    }

    ~some_struct()
    {}
    // Note the below is psedo code
    // Also note member destuction happens after user code.
    // In the compiler generated version the user code is empty
        // PODs dont have destructor
        :~str()
        ,~some_base();
    // End of destructor here.
}

If you want to know why?
It is to maintain backward compatibility with C. But it also makes writting simple classes easier. Some would argue that it adds problems because of the "shallow copy problem". My argument against that is that you should not have a class with owned RAW pointers in it. By using the appropriate smart pointers that problem goes away.

Default Constructor (If no othere constructors are defined)

The compiler generated default constructor will call the base classes default contructor and then each memebers default constructor (in the order they are declared)

Destructor (If no destructor defined)

Calls the destructor of each member in reverse order of declaration. Then calls the destructor of the base class.

Copy Constructor (If no copy constructor is defined)

Calls the base class copy constructor passing the src object. Then calls the copy constructor of each member using the src objects members as the value to be copied.

Assignment Operator

Calls the base class assingment operator passsing the src object. Then calls the assignment operator on each member using the src object as the value to be copied.

Martin York