【问题标题】:copy constructor knowlege拷贝构造函数知识
【发布时间】:2012-03-12 04:49:41
【问题描述】:

我读过的关于复制构造函数实现的大多数帖子是,您还必须重载赋值运算符。我不明白为什么这是真的。我可以在不进行任何运算符重载的情况下实现复制构造函数,并且工作正常。你能解释一下我缺少什么或为什么我需要遵循这个协议吗?

下面是一些基本代码,它们的工作方式与我期望的一样:

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

感谢您的信息

【问题讨论】:

  • 看起来您正在尝试用 C++ 编写 Java。不要,C++ 中的良好实践有很大不同。例如,将琐碎的访问器(例如getNamesetName)内联函数定义在类中,您现在拥有的内容会削弱优化器。并了解 ctor-initializer-lists
  • 最后,这里没有充分的理由使用指针(但您的文件名表明您已经知道这一点并且只是为了练习而使用它们)。但是,如果您要练习使用指针,请练习正确释放内存(使用delete)。
  • @Ben 你能告诉我关于“练习正确释放内存”的意思吗?我的理解是你不要删除字符串和原始数据类型,如整数。事实上,这会在 Xcode 中产生错误,所以对于这个特别简单的类,我认为使用带有空括号的析构函数是合适的。
  • @Miek:firstPtr = new Event() 后面应该跟delete firstPtr,否则你会泄漏内存。

标签: c++ copy-constructor assignment-operator


【解决方案1】:

赋值运算符不会以任何方式影响复制构造函数,您可以在没有赋值运算符的情况下定义复制构造函数。

但是你愿意吗?需要自定义复制行为的类通常希望该自定义行为适用于复制构造和复制分配。这就是规则 3(现在是 5)的基本原理。如果您有原始指针或其他无法默认复制和默认销毁的成员,则默认复制赋值运算符可能也不正确。

当然,如果您不喜欢默认值,直接禁用复制赋值运算符而不是编写新的,这是完全合理的。

对于您的特定代码,您是对的,您不需要自定义复制赋值运算符。但是您也不需要自定义复制构造函数,因为默认行为已经是您想要的了。事实上,编译器生成的默认复制构造函数比您定义的要好,因为它会复制构造成员而不是默认构造然后重新分配。

【讨论】:

  • 你所说的一切都很有道理,一个例外是如果我不使用复制构造函数,那么两个对象的最终事件开始时间的值是相同的。 (因为第二个对象的指针可以操作第一个对象)。如果我实现了复制构造函数(如代码中所示),情况并非如此
  • @Miek:您需要使用复制构造函数,但不需要定义它。编译器将提供一个非常好的编译器。
  • 哦,好的,我明白你在说什么。谢谢。我的老板总是说定义复制构造函数总是带走默认的,如果你不需要它,把它放在 .h 文件的受保护部分
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-09
  • 2012-11-11
  • 1970-01-01
  • 2013-03-19
  • 2018-11-05
相关资源
最近更新 更多