1.假設string
類有如下私有成員:
class string
b.下述建構函式有什麼問題?
string::string(const char* s)
{str=s;
len=strlen(s);
c.下述建構函式有什麼問題?
string::string(const char*a)
{strcpy(str,s);
len=strlen(s);
答:a的問題在於,
char*str
由於需要通過
new來分配記憶體,因此建構函式、複製建構函式、析構函式,都有對應的
new或者
delete
。而這裡至少需要宣告是空指標,才可以,否則在遇見
delete
時,會提示出錯。
b的問題在於
str不能直接指向傳遞的字串
s。這可能導致多個物件指向同乙個記憶體位址,或者指向乙個由
new分配的記憶體位址但這個位址之後又被
delete
釋放(因此使用該物件會出錯)。而
len這行**應該放在最先。
c的問題在於,應該先用
len=strlen(s),然後str=new char[len+1];
,然後再使用
strcpy()函式。
2.如果您定義了乙個類,其指標成員是使用
new初始化的,請指出可能出現的
3個問題,以及如何糾正這些問題。 答:
可能①:只有乙個建構函式使用了new
來分配,其他比如預設建構函式、複製建構函式、建構函式未使用
new來分配記憶體。
解決:應同時都使用。
可能②:析構函式沒有使用delete
釋放記憶體。
解決:析構函式應該使用delete
釋放記憶體。
可能③:未自定義預設賦值運算子(物件導向的)。
解決:賦值運算子應自定義,且使用new
來分配記憶體,
strcpy()函式來拷貝字串內容。
可能④:指標直接指向某作為引數的字串。
解決:指標應該指向由new
分配,由
strcpy()拷貝後的記憶體位址。
3.如果沒有顯式的提供類方法,編譯器將自動生成哪些類方法?請描述這些隱式生成的函式的行為。 答:
①預設建構函式。無賦值,單純初始化各個資料成員;
②析構函式。無任何操作;
③複製建構函式。按值將被複製的物件傳遞給被初始化的物件;
④賦值運算子(把乙個物件賦值給另乙個物件的)。逐成員賦值傳遞;
⑤位址運算子。(返回this
指標的值)
4.找出並改正下述類宣告中的錯誤:
class nifty
//data
char personality;
int talents;
//methods
nifty();
nifty(char*s);
ostream & operator<<(ostream&os, nifty&n);
nifty:nifty()
{personality=null;
talents=0;
nifty:nifty(char*s)
personality = new char [strlen(s)];
personality =s;
talents = 0;
ostream & nifty:operator<<(ostream & os, nifty &n)
os《答:
錯誤0:類名首字母一般大寫,但不是強制規定。
錯誤①:看上下文,char personality應該想要宣告的是char
指標,而不是乙個不確定字元數的字串,因此應該用char * personality; char指標和字串占用的記憶體空間是不一樣的
錯誤②:公共部分沒有寫public
,在類方法和資料之間加上。
錯誤③:ostream&
那個函式,應該是友元函式,應該在之前加上
friend
錯誤④:作用域解析運算子是「::」,而不是「:」,兩個類方法都應該加上。
錯誤⑤:nifty::nifty(char*s)看意思是要複製指標的字串給自己。一是new
分配的空間少
1,二是沒有正確使用拷貝,三不太確定
talents
要初始化為什麼,貌似是要初始化為
0。因此修改為:
nifty::nifty(char * s)
personality = new char[strlen(s)+1];
strcpy(personality, s);
talents=0;
錯誤⑥友元函式無需加作用域解析運算子,函式內部寫錯。應該改為:
ostream & operator<<(ostream & os, nifty & n)
os《錯誤⑦類定義結束
後沒有分號
錯誤⑧nifty:nifty(char*s)
一般寫成
nifty::nifty(const char *s)
錯誤⑨ostream & nifty:operator<<(ostream & os, nifty &n)
一般寫為:
ostream & nifty:operator<<(ostream & os,
const
nifty &n)
——加上cosnt
5.對於下面的類宣告:
class golfer
private:
char * fullname; // points to string containing golfer's name
int games; // holds number of golf games played
int * scores; // points to first element of array of golf scores
public:
golfer();
golfer(const char * name, int g=0);
//creates empty dynamic array of g elements if g > 0
golfer(const golfer & g);
~golfer();
a.下面各條語句將呼叫哪些類方法
golfer nacy; //#1
golfer lulu("little lulu"); //#2
golfer roy("roy hobbs",12); //#3
golfer * par = new golfer; //#4
golfer next = lulu; //#5
golfer hazzard = "weed thwacker"; //#6
*par = nancy; //#7
nancy = "nancy putter"; //#8
b.很明顯,類需要有另外幾個方法才能更有用,但是,類需要哪些方法才能防止資料被損壞呢?
答:a.
1#將呼叫預設建構函式
golfer()
2#將呼叫建構函式golfer(const char * name, int g=0);
3#將呼叫建構函式golfer(const char * name, int g=0);
4#將呼叫預設建構函式golfer();
5#將呼叫複製建構函式golfer(const golfer & g);
6#將呼叫建構函式golfer(const char * name, int g=0);
7#將什麼也不呼叫,單純將指標指向類物件。
7#將呼叫賦值運算子(隱式生成的),我沒注意到
par指標在
4#宣告了
8#將呼叫建構函式golfer(const char * name, int g=0);和隱式生成的賦值運算子
b.為了防止資料損壞,有以下方法:
①防止拷貝,將賦值運算子(物件導向拷貝給物件的)/複製建構函式,放在私有部分;
②自定義賦值運算子/複製建構函式,讓其在複製的時候,避免按值傳遞,讓其通過new
、strcpy()函式等方式拷貝資料。
程式設計珠璣第十二章習題
1.rand 一般返回約15個隨機位。用該函式實現bigrand 和randint l,u 要求前者至少返回30個隨機位,後者返回 l,u 範圍內的乙個隨機整數。int bigrand int randint int l,int u 2.在0 n 1範圍內選擇m個整數,在該範圍內隨機選擇乙個數i,然...
第十二章 檔案
文字檔案 文字檔案是一種由若干字元構成的檔案,可以用文字編輯器進行閱讀或編輯。以txt py html等為字尾的檔案都是文字檔案。2.二進位制檔案 二進位制檔案一般是指不能用文字編輯器閱讀或編輯的檔案。以 mp4 png等為字尾的檔案都是二進位制檔案,如果想要開啟或修改這些檔案,必須通過特定軟體進行...
第十二章 dp
動態規劃策略 將原始問題拆分為多個子問題,將子問題結果記錄,方便復用子問題的解 遞迴 記憶化 遞推 是動態規劃的一體兩面,本質都是一樣的 遞推減少了呼叫次數,空間上還能優化,一般選擇遞推方式 遞迴 記憶化 int memo maxn 將o 2 n o n intfibonacci int n 遞推 ...