2017-05-25 67 views
-1

試圖熟悉「3規則」,並且無法讓複製構造函數工作。其中一個類私有成員返回0時,它應該有一個值3.動態分配數組的複製構造函數

我不知道爲什麼當複製構造函數執行時,爲該類私有成員提供值爲0。有問題的成員是theSize,它是通過class.cpp中的size()函數返回的。

class.h

class Catalog { 
public: 
    Catalog (int maxCapacity = 100) 
    int size() const; 
    int capacity() const; 
    void add (Book b); 
    Catalog(const Catalog& c); 
    ~Catalog(); 
    Catalog& operator= (constCatalog& c) { 
     if (this != &c) { 
      delete[] books; 
      books = new Book[theCapacity]; 
      *books = *(c.books); 
     } 
     return *this; 
    } 
private: 
    Book* books; 
    int theCapacity; 
    int theSize; 
}; 

class.cpp

Catalog::Catalog(int maxCapacity) { 
    theCapacity = maxCapacity; 
    theSize = 0; 
    books = new Book[theCapacity]; 
} 

int Catalog::size() const { 
    return theSize(); 
} 

int Catalog::capacity() const { 
    return theCapacity; 
} 

void Catalog::add (Book b) 
{ 
    if (theSize < theCapacity || contains(b.getID())) { 
     if (theSize == 0) { 
      books[0] = b; 
      theSize++; 
     } 
     else { 
      if (!contains(b.getID())) { 
       int i = theSize; 
       for (; i && b < books[i-1]; --i) { 
        books[i] = books[i - 1]; 
       } 
       books[i] = b; 
       for (; i; --i) { 
        books[i - 1] = books[i - 1]; 
       }  
       theSize++; 
      } 
      else { 
       for (int i = 0; i < theSize; ++i) { 
        if (b == books[i]) { 
         books[i] = b; 
        } 
       } 
      } 
     } 
     // Debugging only 
     /*for (int i = 0; i < theSize; i++) { 
      //cout << books[i] << endl; 
     }*/ 
    } 
} 

bool Catalog::contains(std::string bookID) const 
{ 
    for (int i = 0; i < theSize; ++i) 
    { 
     if (books[i].getID() == bookID) 
      return true; 
    } 
    return false; 
} 

Catalog::Catalog(const Catalog& c) { 
    books = new Book[c.theSize]; 
    for (int i = 0; i < c.theSize; i++) { 
     books[i] = c.books[i]; 
} 

Catalog::~Catalog() { 
    delete[] books; 
} 

c1return c在另一個函數的結果,當我打電話c1.size()的main.cpp後來,通過使用的調試器來自複製構造函數,然後進入析構函數。但c1.size()返回爲0,雖然複製構造函數theSize = c.size()的值爲3時,通過。

book.cpp

using namespace std; 


/** 
* Create a book. 
* 
* @param id the Gutenberg ID for this book 
* @param authorInfo the author of the book 
* @param title the title of the book 
*/ 
Book::Book (std::string theId, std::string authorInfo, std::string theTitle) 
    : id(theId), authorName(authorInfo), title(theTitle) 
{ 
} 


bool Book::operator< (const Book& b) const 
{ 
    return id < b.id; 
} 


bool Book::operator== (const Book& b) const 
{ 
    return (id == b.id); 
} 

std::ostream& operator<< (std::ostream& out, const Book& b) 
{ 
    cout << b.getID() << "\t" 
      << b.getAuthor() << "\t" 
      << b.getTitle(); 
    return out; 
} 


std::istream& operator>> (std::istream& in, Book& b) 
{ 
    string line; 
    getline (in, line); 
    if (!in.good()) 
    return in; 
    int tab1 = line.find ("\t"); 
    int tab2 = line.find ("\t", tab1+1); 
    string id = line.substr(0, tab1); 
    string author = line.substr (tab1+1, tab2-tab1-1); 
    string title = line.substr(tab2+1); 
    b.setID (id); 
    b.setAuthor (author); 
    b.setTitle (title); 
    return in; 
} 

main.cpp中的零

using namespace std; 



Catalog readCatalog(const string& fileName) 
{ 
    Catalog c; 
    ifstream in (fileName); 
    in >> c; 
    in.close(); 
    return c; 
} 


Catalog mergeCatalogs (const Catalog& cat1, const Catalog& cat2) 
{ 
    Catalog result (cat1.size() + cat2.size()); 
    int i = 0; 
    int j = 0; 
    while (i < cat1.size() && j < cat2.size()) 
    { 
     Book b1 = cat1.get(i); 
     Book b2 = cat2.get(j); 
     if (b1.getID() < b2.getID()) 
     { 
      result.add(b1); 
      ++i; 
     } 
     else 
     { 
      result.add(b2); 
      ++j; 
     } 
    } 
    while (i < cat1.size()) 
    { 
     result.add(cat1.get(i)); 
     ++i; 
    } 
    while (j < cat2.size()) 
    { 
     result.add(cat2.get(j)); 
     ++j; 
    } 
    return result; 
} 


void mergeCatalogFiles (const string& catalogFile1, const string& catalogFile2) 
{ 
    Catalog c1, c2; 
    c1 = readCatalog(catalogFile1); 
    cout << catalogFile1 << " contained " << c1.size() << " books." << endl; 
    c2 = readCatalog(catalogFile2); 
    cout << catalogFile2 << " contained " << c2.size() << " books." << endl; 
    Catalog c3 = mergeCatalogs (c1, c2); 
    cout << "Their merge contains " << c3.size() << " books." << endl; 
    cout << c3 << flush; 
} 

int main (int argc, char** argv) 
{ 
    if (argc != 3) 
    { 
     cerr << "Usage: " << argv[0] << 
       "catalogFile1 catalogFile2" << endl; 
     return -1; 
    } 
    string file1 = argv[1]; 
    string file2 = argv[2]; 
    mergeCatalogFiles (file1, file2); 
    if (Counted::getCurrentCount() == 0) 
    { 
     cout << "No memory leak detected." << endl; 
     return 0; 
    } 
    else 
    { 
     cout << "Memory leak detected: " << Counted::getCurrentCount() << endl; 
     return -2; 
    } 
} 
+2

'*書籍= *(c.books);'將一個元素,而不是整個數組 – user4581301

+0

複製@ user4581301所以也許'for'循環來複制?還是有更好的方法來複制數組? –

+1

For循環或['std :: copy'](http://en.cppreference.com/w/cpp/algorithm/copy)。 – user4581301

回答

1

嘗試一些更喜歡這個:

class Catalog 
{ 
public: 
    Catalog (int maxCapacity = 100); 
    Catalog(const Catalog& c); 
    ~Catalog(); 

    int size() const; 
    int capacity() const; 

    void add (const Book &b); 
    Book* find(const std::string &bookID) const; 

    Catalog& operator= (Catalog c); 

private: 
    Book* books; 
    int theCapacity; 
    int theSize; 

    void swap(Catalog &c); 
}; 

#include "class.h" 
#include <algorithm> 

Catalog::Catalog(int maxCapacity) 
{ 
    theCapacity = maxCapacity; 
    theSize = 0; 
    books = new Book[theCapacity]; 
} 

Catalog::Catalog(const Catalog& c) 
{ 
    theCapacity = c.theCapacity; 
    books = new Book[theCapacity]; 
    for(int i = 0; i < c.theSize;; ++i) 
     books[i] = c.books[i]; 
    theSize = c.theSize; 
} 

Catalog::~Catalog() 
{ 
    delete[] books; 
} 

Catalog& Catalog::operator= (const Catalog &c) 
{ 
    if (this != &c) 
     Catalog(c).swap(*this);  
    return *this; 
} 

void Catalog::swap(Catalog &c) 
{ 
    std::swap(books, c.books); 
    std::swap(theSize, c.theSize); 
    std::swap(theCapacity, c.theCapacity); 
} 

int Catalog::size() const 
{ 
    return theSize; 
} 

int Catalog::capacity() const 
{ 
    return theCapacity; 
} 

void Catalog::add (const Book &b) 
{ 
    Book *book = find(b.getID()); 
    if (book) { 
     *book = b; 
    } 
    else if (theSize < theCapacity) 
    { 
     int i; 
     for (i = theSize; i && b < books[i-1]; --i) { 
      books[i] = books[i - 1]; 
     } 
     books[i] = b; 
     ++theSize; 
    } 

    // Debugging only 
    /* 
    for (int i = 0; i < theSize; ++i) { 
     cout << books[i] << endl; 
    } 
    */ 
} 

Book* Catalog::find(const std::string &bookID) const 
{ 
    for (int i = 0; i < theSize; ++i) 
    { 
     if (books[i].getID() == bookID) 
      return &books[i]; 
    } 
    return 0; 
} 

話雖這麼說,如果你使用std::vector和STL算法,這將是更簡單,更易於管理。讓STL做的辛勤工作爲您提供:

#include <vector> 

class Catalog 
{ 
public: 
    Catalog (int initialCapacity = 100); 

    int size() const; 
    int capacity() const; 

    void add (const Book &b); 
    Book* find(const std::string &bookID) const; 

private: 
    std::vector<Book> books; 
}; 

#include "class.h" 
#include <algorithm> 

Catalog::Catalog(int initialCapacity) 
{ 
    books.reserve(initialCapacity); 
} 

int Catalog::size() const 
{ 
    return books.size(); 
} 

int Catalog::capacity() const 
{ 
    return books.capacity(); 
} 

void Catalog::add (const Book &b) 
{ 
    Book *book = find(b.getID()); 
    if (book) { 
     *book = b; 
    } 
    else { 
     books.insert(std::upper_bound(books.begin(), books.end(), b), b); 
    } 

    // Debugging only 
    /* 
    for (Book &book: books) { 
     cout << book << endl; 
    } 
    */ 
} 

Book* Catalog::find(const std::string &bookID) const 
{ 
    auto iter = std::find_if(books.begin(), books.end(), [&bookID](const Book &b){ return (b.getID() == bookID); }); 
    if (iter != books.end()) 
     return &*iter; 
    return 0; 
} 
1

關注規則:使用std::vector<Book>來代替數組指針和大小。

您的容量是大小上的限制。

當在能力。使用相等的範圍來找到插入的位置,替換最後一個元素然後std旋轉。

在同一個類中管理資源和業務邏輯很容易出錯。一次做一件事。

+0

絕對是廣義上的正確答案,但是OP有一個明確的目標,就是搞清楚三條規則。 – user4581301

+0

@Yakk寧願堅持三條規則,因爲它更適用於我在不久的將來所做的事情。 –

+0

@pasta然後寫*只*管理資源的東西。兩者都是在腳下射擊自己。 – Yakk