2

Most posts I have read regarding implementation of copy constructor is that you must also overload the assignment operator. I don't understand why that is true. I can implement a copy constructor without doing any operator overloading and it works fine. Can you please explain what I'm missing or why I need to follow this protocol?

Here is some basic code that is working the way I would expect:

//
//  Event.h
//  PointerPractice
//

#ifndef PointerPractice_Event_h
#define PointerPractice_Event_h

#include <string>

class Event{


public:

    Event();

    Event(const Event& source);

    ~Event();

    std::string getName();
    void setname(std::string  theName);

    uint64_t getBeginTime();
    void setBeginTime(uint64_t time);

    uint64_t getDuration();
    void setDuration(uint64_t dur);



private:

    std::string name_;
    uint64_t time_;
    uint64_t duration_;


};
#endif


//
//  Event.cpp
//  PointerPractice
//

#include <iostream>
#include "Event.h"

Event::Event(){

    this->name_ ="";
    this->time_ = 0;
    this->duration_ = 0;
}

Event::Event(const Event& source){

    this->name_ = source.name_;
    this->time_ = source.time_;
    this->duration_ = source.duration_;

}

Event::~Event(){}

std::string Event::getName(){

    return this->name_;
}


void Event::setname(std::string theName){

    this->name_ = theName; 

}


uint64_t Event::getBeginTime(){

    return this->time_;
}

void Event::setBeginTime(uint64_t time){

    this->time_ = time;
}

uint64_t Event::getDuration(){

    return this->duration_;
}

void Event::setDuration(uint64_t dur){

    this->duration_ = dur; 

}




//  main.cpp
//  PointerPractice
//

#include <iostream>
#include <vector>
#include "Event.h"

int main (int argc, const char * argv[])
{

    Event *firstPtr = new Event();
    firstPtr->setname("DMNB");
    firstPtr->setBeginTime(4560000);
    firstPtr->setDuration(2000000);


    std::cout<<"Test first Event object begin time "<<firstPtr->getBeginTime()<<std::endl;


    Event *secPtr = new Event(*firstPtr);


    secPtr->setBeginTime(2222222);
    std::cout<<"Test first Event object begin time "<<firstPtr->getBeginTime()<<std::endl;
    std::cout<<"Test second Event object begin time "<<secPtr->getBeginTime()<<std::endl;


    return 0;
}

Thanks for the info

Miek
  • 1,127
  • 4
  • 20
  • 35
  • See the [Rule of Three](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three). – chrisaycock Mar 12 '12 at 04:52
  • It looks like you're trying to write Java in C++. Don't, the good practices are considerably different in C++. For example, make trivial accessors (such as `getName`, `setName`) inline functions defined inside the class, what you have now cripples the optimizer. And learn about *ctor-initializer-lists*. – Ben Voigt Mar 12 '12 at 04:57
  • Finally, there's no good reason to use pointers here (but your filename suggests you already knew that and are using them just for practice). If you are going to practice with pointers, though, practice freeing the memory properly (with `delete`). – Ben Voigt Mar 12 '12 at 05:04
  • @Ben Could you show me what you mean regarding "Practice freeing memory correctly"? My understanding is you don't delete strings and primitive data types such as ints. In fact, that generates an error in Xcode, so for this particular simple class, I thought having the destructor with empty braces was proper. – Miek Mar 12 '12 at 15:46
  • @Miek: `firstPtr = new Event()` should be followed by `delete firstPtr`, otherwise you leak memory. – Ben Voigt Mar 12 '12 at 21:09

1 Answers1

3

The assignment operator doesn't affect the copy constructor in any way, you CAN define the copy constructor without an assignment operator.

But do you want to? Classes that need custom copy behavior usually want that custom behavior to apply to both copy construction and copy assignment. This is the rationale for the Rule of 3 (now 5). If you have raw pointers or other members that can't be default copied and default destroyed, then the default copy assignment operator probably isn't correct either.

Of course, it's perfectly reasonable to simply disable the copy assignment operator if you don't like the default, instead of writing a new one.

In the case of your particular code, you're right that you don't need a custom copy assignment operator. But you didn't need a custom copy constructor either, since the default behavior would already be what you wanted. In fact, the compiler-generated default copy constructor is better than the one you defined, since it would copy construct members instead of default constructing and then re-assigning.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • Everything you are saying makes good sense, the one exception is that if I don't use a copy constructor, then the value of the final event begin times of both objects are the same. (because the second objects pointer can manipulate the first object). If I implement the copy constructor (as in the code) this is not the case – Miek Mar 12 '12 at 05:02
  • @Miek: You need to USE the copy constructor, but you don't need to define it. The compiler will provide a perfectly good one. – Ben Voigt Mar 12 '12 at 05:04
  • Oh Okay I see what you're saying. Thanks. My boss always says to define the copy constructor always to take away the default one and if you don't need it, put it in the protected section of the .h file – Miek Mar 12 '12 at 05:10