全國統(tǒng)一學(xué)習(xí)專線 8:30-21:00

課程導(dǎo)航
更多

位置:用考培訓(xùn)網(wǎng) > 計算機(jī)類>計算機(jī)等級> 全國計算機(jī)二級C++知識點:類的其他幾點問題

全國計算機(jī)二級C++知識點:類的其他幾點問題

logo
來源:233網(wǎng)校

2018-10-31 11:24:30

進(jìn)入 >

類的其他幾點問題

一、拷貝構(gòu)造函數(shù)

拷貝構(gòu)造函數(shù)在下列情況下被調(diào)用:用已經(jīng)存在的對象去初始化同一個類的另一個對象;在函數(shù)的參數(shù)中,以傳值方式傳遞類對象的拷貝;類對象的值被用做函數(shù)的返回值。拷貝構(gòu)造函數(shù)和前面說到的轉(zhuǎn)換構(gòu)造函數(shù)有些相似。轉(zhuǎn)換構(gòu)造函數(shù)是把一個類的對象轉(zhuǎn)化為另一個類的對象;拷貝構(gòu)造函數(shù)是用一個已經(jīng)存在的對象的值實例化該類的一個新對象。

不同對象間的初始化和賦值的區(qū)別:賦值操作是在兩個已經(jīng)存在的對象間進(jìn)行的;而初始化是要創(chuàng)建一個新的對象,并且其初值來源于另一個已存在的對象。編譯器會區(qū)別這兩種情況,賦值的時候調(diào)用重載的賦值運(yùn)算符,初始化的時候調(diào)用拷貝構(gòu)造函數(shù)。

如果類中沒有拷貝構(gòu)造函數(shù),則編譯器會提供一個默認(rèn)的。這個默認(rèn)的拷貝構(gòu)造函數(shù)只是簡單地復(fù)制類中的每個成員。

#include iostream.h

#include string.h

class Date

{

int mo, da, yr;

char* month;

public:

Date(int m = 0, int d = 0, int y = 0);

Date(const Date &);

~Date();

void display() const;

};

Date::Date(int m, int d, int y)

{

static char* mos[] =

{

January, February, March, April, May, June,

July, August, September, October, November, December

};

mo = m; da = d; yr = y;

if (m != 0)

{

month = new char[strlen(mos[m-1])+1];

strcpy(month, mos[m-1]);

}

else

month = 0;

}

Date::Date(const Date & dt)

{

mo = dt.mo;

da = dt.da;

yr = dt.yr;

if (dt.month != 0)

{

month = new char [strlen(dt.month)+1];

strcpy(month, dt.month);

}

else

month = 0;

}

Date::~Date()

{

delete [] month;

}

void Date::display() const

{

if (month != 0)

cout << month <<' '<< da << , << yr << std::endl;

}

int main()

{

Date birthday(6,24,1940);

birthday.display();

Date newday = birthday;

newday.display();

Date lastday(birthday);

lastday.display();

return 0;

}

本例中,用到了兩次拷貝構(gòu)造函數(shù)。一個是使用普通的C++初始化變量的語句:

Date newday = birthday;

另一個是使用構(gòu)造函數(shù)的調(diào)用約定,即把初始化值作為函數(shù)的參數(shù):

Date lastday(birthday);

二、類的引用

在函數(shù)參數(shù)和返回值中,如果一定要使用傳值方式,那么使用類對象的引用,是一個提高效率的方法。

類的數(shù)據(jù)成員也可以是一個引用,但必須注意:第一,一個引用必須初始化。通常一個類對象并不會像結(jié)構(gòu)那樣用大括號來初始化,而是調(diào)用構(gòu)造函數(shù)。因此在構(gòu)造函數(shù)里必須初始化類當(dāng)中的引用成員。第二,引用是一個別名。盡管類里面的引用在使用方式上看起來和類的一般數(shù)據(jù)成員沒有什么區(qū)別,但是作用在其上的操作,實際上是對用來初始化它的那么對象進(jìn)行的。

#include iostream.h

class Date

{

int da, mo, yr;

public:

Date(int d,int m,int y)

{ da = d; mo = m; yr = y; }

void Display() const

{ cout << da << '/' << mo << '/' << yr; }

};

class Time

{

int hr, min, sec;

public:

Time(int h, int m, int s)

{ hr = h; min = m; sec = s; }

void Display() const

{ cout << hr << ':' << min << ':' << sec; }

};

class DateTime

{

const Date & dt;

const Time & tm;

public:

DateTime(const Date & d, const Time& t) : dt(d), tm(t)

{

//empty

}

void Display() const

{

dt.Display();

cout << ' ';

tm.Display();

}

};

int main()

{

Date today(7,4,2004);

Time now(15,20,0);

DateTime dtm(today, now);

dtm.Display();

return 0;

}

我們來看看這個程序中DateTime的構(gòu)造函數(shù)的格式:冒號操作符引出了一個參數(shù)初始化表。必須使用這種格式來初始化引用數(shù)據(jù)成員,而不可以在函數(shù)體內(nèi)來進(jìn)行初始化工作。如果構(gòu)造函數(shù)像上例一樣不是內(nèi)聯(lián)的,那么最好不要在類聲明中構(gòu)造函數(shù)的原型上使用冒號和初始化值表,而是像下面這樣,把參數(shù)初始化表放在定義構(gòu)造函數(shù)的地方:

Class DateTime

{

const Date & dt;

const Time & tm;

public:

DateTime(const Date & d,const Time& t);

}

DateTime::DateTime(const Date & d,const Time& t):dt(d),tm(t)

{

//empty

}

可以使用構(gòu)造函數(shù)的參數(shù)初始化表來初始化任何數(shù)據(jù)成員。特別是常量數(shù)據(jù)成員,和引用一樣,只能在參數(shù)初始化表里進(jìn)行初始化,這是因為不可以在構(gòu)造函數(shù)內(nèi)部為常量數(shù)據(jù)成員賦值。

當(dāng)一個類含有引用數(shù)據(jù)成員時,一旦引用被實例化和初始化以后,就無法修改它的值,所以該類不可能徹底地重載賦值運(yùn)算符函數(shù)。

三、構(gòu)造函數(shù)的參數(shù)初始化表

如果類對象的某些數(shù)據(jù)成員沒有載構(gòu)造函數(shù)內(nèi)部被初始化,那么必須使用構(gòu)造函數(shù)的參數(shù)初始化表對他們進(jìn)行初始化。否則,編譯器不止到該如何初始化這些還等著在構(gòu)造函數(shù)內(nèi)部賦值的成員。我們習(xí)慣用參數(shù)初始化表來初始化所有數(shù)據(jù)成員。

class Date

{

int mo,da,yr;

public:

Date(int m=0,int d=0,int y=0);

};

class Employee

{

int empno;

Date datehired;

public:

Employee(int en,Date & dh);

};

可以用下面兩種方法編寫Employee類的構(gòu)造函數(shù):

Employee::Employee(int en,Date & dt)

{

empno=en;

datehired=dh;

}

或者;

Employee::Employee(int en,Date & dt):empno(en),datehired(dh)

{

//empty

}

雖然這兩種方法效果是一樣的,但是根據(jù)Date對象默認(rèn)構(gòu)造函數(shù)的復(fù)雜性的不同,這兩種形式的效率差別是很大的。

四、對const修飾符的簡單說明

如果一個對象被聲明為常量,那么該對象就不可以調(diào)用類當(dāng)中任何非常量型的成員函數(shù)(除了被編譯器隱式調(diào)用的構(gòu)造函數(shù)和析構(gòu)函數(shù))??聪旅娴拇a;

#include iostream.h

class Date

{

int month,day,year;

public:

Date(int m,d,y):month(m),day(d),year(y) {}

void display()

{

cout < }

}

int main()

{

const Date dt(4,7,2004);

dt.display(); //error

return 0;

}

這個程序盡管編譯時沒有問題,但運(yùn)行時卻出錯了。這是因為常量對象不能調(diào)用非常量函數(shù)。編譯器只看函數(shù)的聲明,而不在乎函數(shù)的具體實現(xiàn)。實際上函數(shù)的實現(xiàn)可以在程序中的任何地方,也可以是在另一個源代碼文件中,這就超過了編譯器的當(dāng)前可見范圍。

//date.h

class Date

{

int month,day,year;

public:

Date(int m,d,y);

void display();

};

//date.cpp

#include iostream.h

#include date.h

Date::Date(int m,d,y):month(m),day(d),year(y) {}

void Date::display()

{

cout < }

//program.cpp

#include iostream.h

#include date.cpp

int main()

{

const Date dt(4,7,2004);

dt.display();

return 0;

}

解決出錯的問題有兩個方法:第一是聲明display()函數(shù)為常量型的

//in date.h

void display() const

//int date.cpp

void Date::display() const

{

cout < }

另一個解決方式就是省略掉Date對象聲明里的const修飾符。

Date dt(4,7,2004);

還有另一個容易出錯的地方:

void abc(const Date & dt)

{

dt.display(); //error 提示display沒有const修飾符

}

函數(shù)abc()聲明了一個Date對象的常量引用,這說明該函數(shù)不會修改傳遞進(jìn)來的參數(shù)的值。如果Date::display()函數(shù)不是常量型的,那么在函數(shù)abc()里就不能調(diào)用它,因為編譯器會認(rèn)為Date::display()函數(shù)有可能會修改常量的值。

不論類對象是否是常量型的,它必須修改某個數(shù)據(jù)成員的值時,ANSI委員會設(shè)立了mutable關(guān)鍵字。

五、可變的數(shù)據(jù)成員

假設(shè)需要統(tǒng)計某個對象出現(xiàn)的次數(shù),不管它是否是常量。那么類當(dāng)中就應(yīng)該有一個用來計數(shù)的整型數(shù)據(jù)成員。只要用mutable修飾符來聲明該數(shù)據(jù)成員,一個常量型的成員函數(shù)就可以修改它的值。

#include iostream.h

class AValue

{

int val;

mutable int rptct;

public:

AValue(int v) : val(v), rptct(0) { }

~AValue()

{

cout < }

void report() const;

};

void AValue::report() const

{

rptct++;

cout << val << endl;

}

int main()

{

const AValue aval(123);

aval.report();

aval.report();

aval.report();

return 0;

}

以上就是小編為您整理全國計算機(jī)二級C++知識點:類的其他幾點問題的全部內(nèi)容,更多精彩請進(jìn)入計算機(jī)等級欄目查看

  • 推薦課程
  • 相關(guān)學(xué)校
  • 相關(guān)文章
預(yù)約免費試聽

只要一個電話
我們免費為您回電