2012-03-12 216 views
2

我已閱讀關於執行拷貝構造函數的是,你還必須重載賦值運算符的大部分信息。我不明白爲什麼這是真的。我可以實現一個複製構造函數,而不需要進行任何操作符重載,並且工作正常。你能解釋我錯過了什麼,或者爲什麼我需要遵循這個協議?拷貝構造函數knowlege

這裏是工作方式的一些基本代碼我希望:

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

感謝信息

+0

參見[三規則](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three)。 – chrisaycock 2012-03-12 04:52:49

+0

看起來你正在嘗試用C++編寫Java。不要,C++中的良好實踐有很大不同。例如,在類中定義一些簡單的訪問器(比如'getName','setName')內聯函數,現在你已經削弱了優化器的功能。並學習* ctor-initializer-lists *。 – 2012-03-12 04:57:08

+0

最後,沒有什麼好的理由在這裏使用指針(但是你的文件名錶明你已經知道並且正在使用它們只是爲了練習)。但是,如果您要練習指針,可以正確釋放內存(使用'delete')。 – 2012-03-12 05:04:43

回答

3

賦值運算符不影響以任何方式拷貝構造函數,你可以定義沒有賦值運算符的複製構造函數。

但是你要?需要自定義複製行爲的類通常要將該自定義行爲應用於複製構建和複製分配。這是3規則(現在5)的基本原理。如果您有原始指針或其他成員不能被默認複製和默認銷燬,那麼默認的複製賦值操作符可能不正確。

。當然,這是完全合理的,簡單地禁止拷貝賦值運算符,如果你不喜歡默認的,而不是寫一個新的。

在您的特定代碼的情況下,你是對的,你並不需要一個自定義的拷貝賦值運算符。但是你也不需要自定義拷貝構造函數,因爲默認行爲已經是你想要的。事實上,編譯器生成的默認拷貝構造函數比您定義的更好,因爲它會複製構造成員而不是默認構造,然後重新賦值。

+0

一切是有道理的,唯一的例外是,如果我不使用拷貝構造函數,那麼最終事件的價值開始兩個物體的時間相同。 (因爲第二個對象指針可以操縱第一個對象)。如果我實現複製構造函數(如代碼中所示),情況並非如此 – Miek 2012-03-12 05:02:35

+0

@Miek:您需要使用複製構造函數,但不需要定義它。編譯器將提供一個非常好的。 – 2012-03-12 05:04:10

+0

噢好吧,我明白你在說什麼了。謝謝。我的老闆總是說定義拷貝構造函數總是帶走默認的,如果你不需要它,把它放在.h文件的受保護部分 – Miek 2012-03-12 05:10:13