2012-03-12 208 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