1. 程式人生 > >條款12:複製物件時勿忘其每一部分

條款12:複製物件時勿忘其每一部分

  複製物件時要把物件的每一部分都賦值到位,尤其在有基類的時候容易遺漏複製
 

#include<iostream>
using namespace std;
class Date
{
public:
    Date(int d = 1, int m = 1, int w = 1) :day(d), month(m), weekday(w)
    {
        cout << "基類建構函式" << endl;
    }
    Date(const Date& rhs)
    {
        day = rhs.day;
        month = rhs.month;
    }
    Date& operator
=(const Date& rhs) { day = rhs.day; month = rhs.month; return *this; } ~Date() { cout << "基類解構函式" << endl; } void printDay() { cout << month << "月" << day << "日" << "周" << weekday << endl; } private
: int day; int month; int weekday; }; int main() { //忘記了賦值weekend Date day1; Date day2(2, 2, 2); day1 = day2; day1.printDay(); /* 基類建構函式 基類建構函式 2月2日周1 */ system("pause"); }

  在繼承、派生體系中,對於派生類的複製控制函式,也要呼叫基類的複製控制,否則複製、賦值等操作只會作用於派生類特有的資料上:
  

#include<iostream>
using namespace std;
class Date
{
public:
    Date(int d = 1, int m = 1, int w = 1) :day(d), month(m), weekday(w)
    {
        cout << "基類建構函式" << endl;
    }
    Date(const Date& rhs)
    {
        init(rhs);
    }
    Date& operator=(const Date& rhs)
    {
        if (&rhs != this)
        {
            init(rhs);
        }
        return *this;
    }
    ~Date()
    {
        cout << "基類解構函式" << endl;
    }
    void printDay()
    {
        cout << month << "月" << day << "日" << "周" << weekday << endl;
    }
private:
    void init(const Date &rhs)
    {
        day = rhs.day;
        month = rhs.month;
        weekday = rhs.weekday;
    }
public:
    int day;
    int month;
    int weekday;
};
class DetailDay :public Date
{
public:
    DetailDay(const DetailDay& rhs) :year(rhs.year), Date(rhs)
    {
    }
    DetailDay(int y, int m, int d, int w) :year(y), Date(m, d, w)
    {}
    DetailDay& operator=(const DetailDay& rhs)
    {
        Date::operator=(rhs);
        year = rhs.year;
        return *this;
    }
    void printDay()
    {
        cout << year<<"年"<<month << "月" << day << "日" << "周" << weekday << endl;
    }
private:
    int year;
};
int main()
{
    DetailDay dt(2017, 5, 10, 3);
    dt.printDay();
    system("pause");

}

最後有一點需要注意:我們發現,複製建構函式和賦值建構函式裡面很多內容是重複的。此時並不要用一個去呼叫另外一個,良好的程式設計習慣是定義一個init函式,讓這兩個函式都呼叫它,就想像程式中所做的那樣。