Cpp string :: copy函数添加其他字符

时间:2018-11-17 15:00:36

标签: c++ arrays string pointers copy

我在复制构造函数(深复制)中使用string :: copy函数,当我使用它时,它会在字符串中附加一些没有意义的字符。 这是我的主要功能:

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

int main(){


    MusicAlbum msc("a7x","Seize the day",2005);

    cout << msc.getMusicAlbumArtist()   <<endl;
    cout << msc.getMusicAlbumTitle()    <<endl;
    cout << msc.getMusicAlbumYear()     <<endl;

    MusicAlbum msc2(msc);
    cout << msc2.getMusicAlbumArtist()   <<endl;
    cout << msc2.getMusicAlbumTitle()    <<endl;
    cout << msc2.getMusicAlbumYear()     <<endl;
    //MusicAlbum msc3(msc);

    return 0;
}

奇怪的一点是,当我在标题上写a7x而不是Avenged sevenfold时,它没有追加字符。

这是标头SimpleMusicAlbum.h:

#ifndef __SIMPLE_MUSIC_ALBUM_H
#define __SIMPLE_MUSIC_ALBUM_H
#include <string>
using namespace std;
class MusicAlbum {
 public:
    MusicAlbum(const string maArtist = "",
    const string maTitle = "",
    const int maYear = 0);

    ~MusicAlbum();
    MusicAlbum(const MusicAlbum &maToCopy);

    void operator=(const MusicAlbum &right);

    string getMusicAlbumArtist();
    string getMusicAlbumTitle();
    int getMusicAlbumYear();
 private:
    string artist;
    string title;
    int year;
};
#endif

这是SimpleMusicAlbum.cpp:

MusicAlbum::MusicAlbum(const string maArtist,
            const string maTitle,
            const int maYear){
    artist = maArtist;
    title = maTitle;
    year = maYear;

}
//the problem is here
MusicAlbum::MusicAlbum(const MusicAlbum &maToCopy){
    char artistTemp[maToCopy.artist.size()] ;
    char titleTemp[maToCopy.title.size()];

    cout << maToCopy.artist.size() << endl;

    maToCopy.artist.copy(artistTemp, maToCopy.artist.size(), 0);
    artist = artistTemp;
    maToCopy.title.copy(titleTemp,maToCopy.title.size(),0);
    title = titleTemp;
    this->year = maToCopy.year;
}

//same problem occurs here
void MusicAlbum::operator=(const MusicAlbum &right){
    char artistTemp[right.artist.size()];
    char titleTemp[right.title.size()];
    right.artist.copy(artistTemp, right.artist.size(), 0);
    artist = artistTemp;
    right.title.copy(titleTemp,right.title.size(),0);
    title = titleTemp;
    this->year = right.year;
}
//destructor
MusicAlbum::~MusicAlbum(){
    // no allocation, no destruction.
}
//methods
string MusicAlbum::getMusicAlbumArtist() {
    return artist;
}

string MusicAlbum::getMusicAlbumTitle(){
    return title;
}

int MusicAlbum::getMusicAlbumYear(){
    return year;
}

2 个答案:

答案 0 :(得分:3)

标准库容器具有其自己的复制和分配功能。无需手动复制它们。

 MusicAlbum::MusicAlbum(const MusicAlbum    &maToCopy)
 {
     artist  = maToCopy.getMusicAlbumArtist();
     title = maToCopy.getMusicAlbumTitle();
     year = maToCopy.getMusicAlbumYear();   
 }

这是一个可行的示例。

 #include<string>
 #include<iostream>

 using namespace std;

 class MusicAlbum
 {
     public:
      MusicAlbum(string Artist, string Title, int Year):artist(Artist),
      title(Title),
      year(Year)
      {}
      string getTitle(){ return title; }
      string getArtist() { return artist; }
      int getYear() { return year; }
 private:
     string artist;
     string title;
     int year;  
 };

 int main()
 {
     MusicAlbum a{"a7x","albumname",2007};
         MusicAlbum b = a;
         cout << b.getArtist() << " " << b.getTitle() << " " <<   b.getYear() << endl;
 }

答案 1 :(得分:0)

让我们将MusicAlbum类分解为仅其成员变量:

class MusicAlbum 
{
    //...
    string artist;
    string title;
    int year;
};

鉴于这些是成员变量,如果您让编译器进行复制,则制作MusicAlbum的副本是绝对安全的。因此,无需提供用户定义的副本构造函数和赋值运算符。 std::string具有开箱即用的正确复制语义,而int显然是可安全复制的。因此修复很简单:

从班级中删除这些功能

但是,如果MusicAlbum包含指向动态分配的内存或需要处理的资源的指针,或者复制构造函数和赋值运算符的默认编译器实现无法正确提供的某些其他方面,那么可以,您将编写用户定义的副本构造函数/赋值运算符。


那么,如果在不需要提供复制构造函数和赋值运算符的情况下提供它们,会发生什么?

唯一的结果是:

  1. 您正确编写了这些功能。
  2. 您错误地编写了这些函数。

您会认为选项1.可以。也许可以,但是缺点是您编写的版本可能效率低下(比您可能做的更多)。编译器的默认复制/分配将始终正常工作,并且可以高效地编写。

至于选项2.,这就是您的代码所发生的事情。无需调试,只需删除这些功能即可。如果要调试并使这些功能正常运行,则可以直接进入列表中的1项目。因此,您实际上没有任何收获,只需要几分钟或几小时的编写和调试功能就不需要首先编写。

因此,不要浪费时间编写编译器已经为您提供的功能。给定类中的成员变量,编译器将始终正确完成副本。