// tv.h -- Tv and Remote classes
#ifndef TV_H_
#define TV_H_
class Tv
{
public:
friend class Remote; // Remote can access Tv private parts
enum { Off, On };
enum { MinVal, MaxVal = 20 };
enum { Antenna, Cable };
enum { TV, DVD };
Tv(int s = Off, int mc = 125) : state(s), volume(5),
maxchannel(mc), channel(2), mode(Cable), input(TV) {}
void onoff() { state = (state == On) ? Off : On; }
bool ison() const { return state == On; }
bool volup();
bool voldown();
void chanup();
void chandown();
void set_mode() { mode = (mode == Antenna) ? Cable : Antenna; }
void set_input() { input = (input == TV) ? DVD : TV; }
void settings() const; // display all settings
private:
int state; // on or off
int volume; // assumed to be digitized
int maxchannel; // maximum number of channels
int channel; // current channel setting
int mode; // broadcast or cable
int input; // TV or DVD
};
class Remote
{
private:
int mode; // controls TV or DVD
public:
Remote(int m = Tv::TV) : mode(m) {}
bool volup(Tv & t) { return t.volup(); }
bool voldown(Tv & t) { return t.voldown(); }
void onoff(Tv & t) { t.onoff(); }
void chanup(Tv & t) { t.chanup(); }
void chandown(Tv & t) { t.chandown(); }
void set_chan(Tv & t, int c) { t.channel = c; }
void set_mode(Tv & t) { t.set_mode(); }
void set_input(Tv & t) { t.set_input(); }
};
#endif
tv.cpp
// tv.cpp -- methods for the Tv class (Remote methods are inline) #includeuse_tv.cpp#include "tv.h" bool Tv::volup() { if (volume < MaxVal) { volume++; return true; } else return false; } bool Tv::voldown() { if (volume > MinVal) { volume--; return true; } else return false; } void Tv::chanup() { if (channel < maxchannel) channel++; else channel = 1; } void Tv::chandown() { if (channel > 1) channel--; else channel = maxchannel; } void Tv::settings() const { using std::cout; using std::endl; cout << "TV is " << (state == Off ? "Off" : "On") << endl; if (state == On) { cout << "Volume setting = " << volume << endl; cout << "Channel setting = " << channel << endl; cout << "Mode = " << (mode == Antenna ? "antenna" : "cable") << endl; cout << "Input = " << (input == TV ? "TV" : "DVD") << endl; } }
//use_tv.cpp -- using the Tv and Remote classes #include#include "tv.h" int main() { using std::cout; Tv s42; cout << "Initial settings for 42" TV:n"; s42.settings(); s42.onoff(); s42.chanup(); cout << "nAdjusted settings for 42" TV:n"; s42.settings(); Remote grey; grey.set_chan(s42, 10); grey.volup(s42); grey.volup(s42); cout << "n42" settings after using remote:n"; s42.settings(); Tv s58(Tv::On); s58.set_mode(); grey.set_chan(s58, 28); cout << "n58" settings:n"; s58.settings(); // std::cin.get(); return 0; }
执行结果:
Initial settings for 42" TV: TV is Off Adjusted settings for 42" TV: TV is On Volume setting = 5 Channel setting = 3 Mode = cable Input = TV 42" settings after using remote: TV is On Volume setting = 7 Channel setting = 10 Mode = cable Input = TV 58" settings: TV is On Volume setting = 5 Channel setting = 28 Mode = antenna Input = TVtvfm.h
// tvfm.h -- Tv and Remote classes using a friend member
#ifndef TVFM_H_
#define TVFM_H_
class Tv; // forward declaration
class Remote
{
public:
enum State { Off, On };
enum { MinVal, MaxVal = 20 };
enum { Antenna, Cable };
enum { TV, DVD };
private:
int mode;
public:
Remote(int m = TV) : mode(m) {}
bool volup(Tv & t); // prototype only
bool voldown(Tv & t);
void onoff(Tv & t);
void chanup(Tv & t);
void chandown(Tv & t);
void set_mode(Tv & t);
void set_input(Tv & t);
void set_chan(Tv & t, int c);
};
class Tv
{
public:
friend void Remote::set_chan(Tv & t, int c);
enum State { Off, On };
enum { MinVal, MaxVal = 20 };
enum { Antenna, Cable };
enum { TV, DVD };
Tv(int s = Off, int mc = 125) : state(s), volume(5),
maxchannel(mc), channel(2), mode(Cable), input(TV) {}
void onoff() { state = (state == On) ? Off : On; }
bool ison() const { return state == On; }
bool volup();
bool voldown();
void chanup();
void chandown();
void set_mode() { mode = (mode == Antenna) ? Cable : Antenna; }
void set_input() { input = (input == TV) ? DVD : TV; }
void settings() const;
private:
int state;
int volume;
int maxchannel;
int channel;
int mode;
int input;
};
// Remote methods as inline functions
inline bool Remote::volup(Tv & t) { return t.volup(); }
inline bool Remote::voldown(Tv & t) { return t.voldown(); }
inline void Remote::onoff(Tv & t) { t.onoff(); }
inline void Remote::chanup(Tv & t) { t.chanup(); }
inline void Remote::chandown(Tv & t) { t.chandown(); }
inline void Remote::set_mode(Tv & t) { t.set_mode(); }
inline void Remote::set_input(Tv & t) { t.set_input(); }
inline void Remote::set_chan(Tv & t, int c) { t.channel = c; }
#endif
tv1.cpp
// tv1.cpp -- methods for the Tv class (Remote methods are inline) #includeuse_tv1.cpp#include "tvfm.h" bool Tv::volup() { if (volume < MaxVal) { volume++; return true; } else return false; } bool Tv::voldown() { if (volume > MinVal) { volume--; return true; } else return false; } void Tv::chanup() { if (channel < maxchannel) channel++; else channel = 1; } void Tv::chandown() { if (channel > 1) channel--; else channel = maxchannel; } void Tv::settings() const { using std::cout; using std::endl; cout << "TV is " << (state == Off ? "Off" : "On") << endl; if (state == On) { cout << "Volume setting = " << volume << endl; cout << "Channel setting = " << channel << endl; cout << "Mode = " << (mode == Antenna ? "antenna" : "cable") << endl; cout << "Input = " << (input == TV ? "TV" : "DVD") << endl; } }
//use_tv1.cpp -- using the Tv and Remote classes #include#include "tvfm.h" int main() { using std::cout; Tv s42; cout << "Initial settings for 42" TV:n"; s42.settings(); s42.onoff(); s42.chanup(); cout << "nAdjusted settings for 42" TV:n"; s42.settings(); Remote grey; grey.set_chan(s42, 10); grey.volup(s42); grey.volup(s42); cout << "n42" settings after using remote:n"; s42.settings(); Tv s58(Tv::On); s58.set_mode(); grey.set_chan(s58, 28); cout << "n58" settings:n"; s58.settings(); // std::cin.get(); return 0; }
执行结果:
Initial settings for 42" TV: TV is Off Adjusted settings for 42" TV: TV is On Volume setting = 5 Channel setting = 3 Mode = cable Input = TV 42" settings after using remote: TV is On Volume setting = 7 Channel setting = 10 Mode = cable Input = TV 58" settings: TV is On Volume setting = 5 Channel setting = 28 Mode = antenna Input = TVqueuetp.h
// queuetp.h -- queue template with a nested class #ifndef QUEUETP_H_ #define QUEUETP_H_ templatenested.cppclass QueueTP { private: enum { Q_SIZE = 10 }; // Node is a nested class definition class Node { public: Item item; Node * next; Node(const Item & i) :item(i), next(0) { } }; Node * front; // pointer to front of Queue Node * rear; // pointer to rear of Queue int items; // current number of items in Queue const int qsize; // maximum number of items in Queue QueueTP(const QueueTP & q) : qsize(0) {} QueueTP & operator=(const QueueTP & q) { return *this; } public: QueueTP(int qs = Q_SIZE); ~QueueTP(); bool isempty() const { return items == 0; } bool isfull() const { return items == qsize; } int queuecount() const { return items; } bool enqueue(const Item &item); // add item to end bool dequeue(Item &item); // remove item from front }; // QueueTP methods template QueueTP - ::QueueTP(int qs) : qsize(qs) { front = rear = 0; items = 0; } template
QueueTP - ::~QueueTP() { Node * temp; while (front != 0) // while queue is not yet empty { temp = front; // save address of front item front = front->next;// reset pointer to next item delete temp; // delete former front } } // Add item to queue template
bool QueueTP - ::enqueue(const Item & item) { if (isfull()) return false; Node * add = new Node(item); // create node // on failure, new throws std::bad_alloc exception items++; if (front == 0) // if queue is empty, front = add; // place item at front else rear->next = add; // else place at rear rear = add; // have rear point to new node return true; } // Place front item into item variable and remove from queue template
bool QueueTP - ::dequeue(Item & item) { if (front == 0) return false; item = front->item; // set item to first item in queue items--; Node * temp = front; // save location of first item front = front->next; // reset front to next item delete temp; // delete former first item if (items == 0) rear = 0; return true; } #endif
// nested.cpp -- using a queue that has a nested class #include#include #include "queuetp.h" int main() { using std::string; using std::cin; using std::cout; QueueTP cs(5); string temp; while (!cs.isfull()) { cout << "Please enter your name. You will be " "served in the order of arrival.n" "name: "; getline(cin, temp); cs.enqueue(temp); } cout << "The queue is full. Processing begins!n"; while (!cs.isempty()) { cs.dequeue(temp); cout << "Now processing " << temp << "...n"; } // cin.get(); return 0; }
执行结果:
Please enter your name. You will be served in the order of arrival. name: Kinsey Millhone Please enter your name. You will be served in the order of arrival. name: Adam Dalgliesh Please enter your name. You will be served in the order of arrival. name: Andrew Dalziel Please enter your name. You will be served in the order of arrival. name: Kay Scarpetta Please enter your name. You will be served in the order of arrival. name: Richard Jury The queue is full. Processing begins! Now processing Kinsey Millhone... Now processing Adam Dalgliesh... Now processing Andrew Dalziel... Now processing Kay Scarpetta... Now processing Richard Jury...error1.cpp
//error1.cpp -- using the abort() function #include#include double hmean(double a, double b); int main() { double x, y, z; std::cout << "Enter two numbers: "; while (std::cin >> x >> y) { z = hmean(x, y); std::cout << "Harmonic mean of " << x << " and " << y << " is " << z << std::endl; std::cout << "Enter next set of numbers : "; } std::cout << "Bye!n"; return 0; } double hmean(double a, double b) { if (a == -b) { std::cout << "untenable arguments to hmean()n"; std::abort(); } return 2.0 * a * b / (a + b); }
执行结果:
Enter two numbers: 3 6 Harmonic mean of 3 and 6 is 4 Enter next set of numberserror2.cpp: 10 -10 untenable arguments to hmean()
//error2.cpp -- returning an error code #include#include // (or float.h) for DBL_MAX bool hmean(double a, double b, double * ans); int main() { double x, y, z; std::cout << "Enter two numbers: "; while (std::cin >> x >> y) { if (hmean(x, y, &z)) std::cout << "Harmonic mean of " << x << " and " << y << " is " << z << std::endl; else std::cout << "One value should not be the negative " << "of the other - try again.n"; std::cout << "Enter next set of numbers : "; } std::cout << "Bye!n"; return 0; } bool hmean(double a, double b, double * ans) { if (a == -b) { *ans = DBL_MAX; return false; } else { *ans = 2.0 * a * b / (a + b); return true; } }
执行结果:
Enter two numbers: 3 6 Harmonic mean of 3 and 6 is 4 Enter next set of numberserror3.cpp: 10 -10 One value should not be the negative of the other - try again. Enter next set of numbers: 1 19 Harmonic mean of 1 and 19 is 1.9 Enter next set of numbers: q Bye!
// error3.cpp -- using an exception #includedouble hmean(double a, double b); int main() { double x, y, z; std::cout << "Enter two numbers: "; while (std::cin >> x >> y) { try { // start of try block z = hmean(x, y); } // end of try block catch (const char * s) // start of exception handler { std::cout << s << std::endl; std::cout << "Enter a new pair of numbers: "; continue; } // end of handler std::cout << "Harmonic mean of " << x << " and " << y << " is " << z << std::endl; std::cout << "Enter next set of numbers : "; } std::cout << "Bye!n"; return 0; } double hmean(double a, double b) { if (a == -b) throw "bad hmean() arguments: a = -b not allowed"; return 2.0 * a * b / (a + b); }
执行结果:
Enter two numbers: 3 6 Harmonic mean of 3 and 6 is 4 Enter next set of numbersexc_mean.h: 10 -10 One value should not be the negative of the other - try again. Enter next set of numbers: 1 19 Harmonic mean of 1 and 19 is 1.9 Enter next set of numbers: q Bye!
// exc_mean.h -- exception classes for hmean(), gmean() #includeerror4.cppclass bad_hmean { private: double v1; double v2; public: bad_hmean(double a = 0, double b = 0) : v1(a), v2(b) {} void mesg(); }; inline void bad_hmean::mesg() { std::cout << "hmean(" << v1 << ", " << v2 << "): " << "invalid arguments: a = -bn"; } class bad_gmean { public: double v1; double v2; bad_gmean(double a = 0, double b = 0) : v1(a), v2(b) {} const char * mesg(); }; inline const char * bad_gmean::mesg() { return "gmean() arguments should be >= 0n"; }
//error4.cpp using exception classes #include#include // or math.h, unix users may need -lm flag #include "exc_mean.h" // function prototypes double hmean(double a, double b); double gmean(double a, double b); int main() { using std::cout; using std::cin; using std::endl; double x, y, z; cout << "Enter two numbers: "; while (cin >> x >> y) { try { // start of try block z = hmean(x,y); cout << "Harmonic mean of " << x << " and " << y << " is " << z << endl; cout << "Geometric mean of " << x << " and " << y << " is " << gmean(x,y) << endl; cout << "Enter next set of numbers : "; }// end of try block catch (bad_hmean & bg) // start of catch block { bg.mesg(); cout << "Try again.n"; continue; } catch (bad_gmean & hg) { cout << hg.mesg(); cout << "Values used: " << hg.v1 << ", " << hg.v2 << endl; cout << "Sorry, you don't get to play any more.n"; break; } // end of catch block } cout << "Bye!n"; // cin.get(); // cin.get(); return 0; } double hmean(double a, double b) { if (a == -b) throw bad_hmean(a,b); return 2.0 * a * b / (a + b); } double gmean(double a, double b) { if (a < 0 || b < 0) throw bad_gmean(a,b); return std::sqrt(a * b); }
执行结果:
Enter two numbers: 4 12 Harmonic mean of 4 and 12 is 6 Geometric mean of 4 and 12 is 6.9282 Enter next set of numberserror5.cpp: 5 -5 hmean(5, -5): invalid arguments: a = -b Try again. 5 -2 Harmonic mean of 5 and -2 is -6.66667 gmean() arguments should be >= 0 Values used: 5, -2 Sorry, you don't get to play any more. B
//error5.cpp -- unwinding the stack #include#include // or math.h, unix users may need -lm flag #include #include "exc_mean.h" class demo { private: std::string word; public: demo(const std::string & str) { word = str; std::cout << "demo " << word << " createdn"; } ~demo() { std::cout << "demo " << word << " destroyedn"; } void show() const { std::cout << "demo " << word << " lives!n"; } }; // function prototypes double hmean(double a, double b); double gmean(double a, double b); double means(double a, double b); int main() { using std::cout; using std::cin; using std::endl; double x, y, z; { demo d1("found in block in main()"); cout << "Enter two numbers: "; while (cin >> x >> y) { try { // start of try block z = means(x, y); cout << "The mean mean of " << x << " and " << y << " is " << z << endl; cout << "Enter next pair: "; } // end of try block catch (bad_hmean & bg) // start of catch block { bg.mesg(); cout << "Try again.n"; continue; } catch (bad_gmean & hg) { cout << hg.mesg(); cout << "Values used: " << hg.v1 << ", " << hg.v2 << endl; cout << "Sorry, you don't get to play any more.n"; break; } // end of catch block } d1.show(); } cout << "Bye!n"; // cin.get(); // cin.get(); return 0; } double hmean(double a, double b) { if (a == -b) throw bad_hmean(a, b); return 2.0 * a * b / (a + b); } double gmean(double a, double b) { if (a < 0 || b < 0) throw bad_gmean(a, b); return std::sqrt(a * b); } double means(double a, double b) { double am, hm, gm; demo d2("found in means()"); am = (a + b) / 2.0; // arithmetic mean try { hm = hmean(a, b); gm = gmean(a, b); } catch (bad_hmean & bg) // start of catch block { bg.mesg(); std::cout << "Caught in means()n"; throw; // rethrows the exception } d2.show(); return (am + hm + gm) / 3.0; }
执行结果:
demo found in block in main() created Enter two numbers: 6 12 demo found in means() created demo found in means() lives! demo found in means() destroyed The mean mean of 6 and 12 is 8.49509 Enter next pair: 6 -6 demo found in means() created hmean(6, -6): invalid arguments: a = -b Caught in means() demo found in means() destroyed hmean(6, -6): invalid arguments: a = -b Try again. 6 -8 demo found in means() created demo found in means() destroyed gmean() arguments should be >= 0 Values used: 6, -8 Sorry, you don't get to play any more. demo found in block in main() lives! demo found in block in main() destroyed Bye!newexcp.cpp
// newexcp.cpp -- the bad_alloc exception #include#include #include // for exit(), EXIT_FAILURE using namespace std; struct Big { double stuff[20000]; }; int main() { Big * pb; try { cout << "Trying to get a big block of memory:n"; pb = new Big[10000]; // 1,600,000,000 bytes cout << "Got past the new request:n"; } catch (bad_alloc & ba) { cout << "Caught the exception!n"; cout << ba.what() << endl; exit(EXIT_FAILURE); } cout << "Memory successfully allocatedn"; pb[0].stuff[0] = 4; cout << pb[0].stuff[0] << endl; delete[] pb; // cin.get(); return 0; }
执行结果:
Trying to get a big block of memory: Got past the new request: Memory successfully allocated 4sales.h
// sales.h -- exceptions and inheritance #includesales.cpp#include class Sales { public: enum { MonTHS = 12 }; // could be a static const class bad_index : public std::logic_error { private: int bi; // bad index value public: explicit bad_index(int ix, const std::string & s = "Index error in Sales objectn"); int bi_val() const { return bi; } virtual ~bad_index() throw() {} }; explicit Sales(int yy = 0); Sales(int yy, const double * gr, int n); virtual ~Sales() { } int Year() const { return year; } virtual double operator[](int i) const; virtual double & operator[](int i); private: double gross[MONTHS]; int year; }; class LabeledSales : public Sales { public: class nbad_index : public Sales::bad_index { private: std::string lbl; public: nbad_index(const std::string & lb, int ix, const std::string & s = "Index error in LabeledSales objectn"); const std::string & label_val() const { return lbl; } virtual ~nbad_index() throw() {} }; explicit LabeledSales(const std::string & lb = "none", int yy = 0); LabeledSales(const std::string & lb, int yy, const double * gr, int n); virtual ~LabeledSales() { } const std::string & Label() const { return label; } virtual double operator[](int i) const; virtual double & operator[](int i); private: std::string label; };
// sales.cpp -- Sales implementation
#include "sales.h"
using std::string;
Sales::bad_index::bad_index(int ix, const string & s)
: std::logic_error(s), bi(ix)
{
}
Sales::Sales(int yy)
{
year = yy;
for (int i = 0; i < MONTHS; ++i)
gross[i] = 0;
}
Sales::Sales(int yy, const double * gr, int n)
{
year = yy;
int lim = (n < MONTHS) ? n : MONTHS;
int i;
for (i = 0; i < lim; ++i)
gross[i] = gr[i];
// for i > n and i < MonTHS
for (; i < MONTHS; ++i)
gross[i] = 0;
}
double Sales::operator[](int i) const
{
if (i < 0 || i >= MONTHS)
throw bad_index(i);
return gross[i];
}
double & Sales::operator[](int i)
{
if (i < 0 || i >= MONTHS)
throw bad_index(i);
return gross[i];
}
LabeledSales::nbad_index::nbad_index(const string & lb, int ix,
const string & s) : Sales::bad_index(ix, s)
{
lbl = lb;
}
LabeledSales::LabeledSales(const string & lb, int yy)
: Sales(yy)
{
label = lb;
}
LabeledSales::LabeledSales(const string & lb, int yy, const double * gr, int n)
: Sales(yy, gr, n)
{
label = lb;
}
double LabeledSales::operator[](int i) const
{
if (i < 0 || i >= MONTHS)
throw nbad_index(Label(), i);
return Sales::operator[](i);
}
double & LabeledSales::operator[](int i)
{
if (i < 0 || i >= MONTHS)
throw nbad_index(Label(), i);
return Sales::operator[](i);
}
use_sales.cpp
// use_sales.cpp -- nested exceptions #include#include "sales.h" int main() { using std::cout; using std::cin; using std::endl; double vals1[12] = { 1220, 1100, 1122, 2212, 1232, 2334, 2884, 2393, 3302, 2922, 3002, 3544 }; double vals2[12] = { 12, 11, 22, 21, 32, 34, 28, 29, 33, 29, 32, 35 }; Sales sales1(2011, vals1, 12); LabeledSales sales2("Blogstar", 2012, vals2, 12); cout << "First try block:n"; try { int i; cout << "Year = " << sales1.Year() << endl; for (i = 0; i < 12; ++i) { cout << sales1[i] << ' '; if (i % 6 == 5) cout << endl; } cout << "Year = " << sales2.Year() << endl; cout << "Label = " << sales2.Label() << endl; for (i = 0; i <= 12; ++i) { cout << sales2[i] << ' '; if (i % 6 == 5) cout << endl; } cout << "End of try block 1.n"; } catch (LabeledSales::nbad_index & bad) { cout << bad.what(); cout << "Company: " << bad.label_val() << endl; cout << "bad index: " << bad.bi_val() << endl; } catch (Sales::bad_index & bad) { cout << bad.what(); cout << "bad index: " << bad.bi_val() << endl; } cout << "nNext try block:n"; try { sales2[2] = 37.5; sales1[20] = 23345; cout << "End of try block 2.n"; } catch (LabeledSales::nbad_index & bad) { cout << bad.what(); cout << "Company: " << bad.label_val() << endl; cout << "bad index: " << bad.bi_val() << endl; } catch (Sales::bad_index & bad) { cout << bad.what(); cout << "bad index: " << bad.bi_val() << endl; } cout << "donen"; // std::cin.get(); return 0; }
执行结果:
First try block: Year = 2011 1220 1100 1122 2212 1232 2334 2884 2393 3302 2922 3002 3544 Year = 2012 Label = Blogstar 12 11 22 21 32 34 28 29 33 29 32 35 Index error in LabeledSales object Company: Blogstar bad index: 12 Next try block: Index error in Sales object bad index: 20 doneERROR解决:
使用了可能未初始化的本地指针变量“p”
rtti1.cpp将Grand * p;
改为 Grand * p = nullptr;
// rtti1.cpp -- using the RTTI dynamic_cast operator #include#include #include using std::cout; class Grand { private: int hold; public: Grand(int h = 0) : hold(h) {} virtual void Speak() const { cout << "I am a grand class!n"; } virtual int Value() const { return hold; } }; class Superb : public Grand { public: Superb(int h = 0) : Grand(h) {} void Speak() const { cout << "I am a superb class!!n"; } virtual void Say() const { cout << "I hold the superb value of " << Value() << "!n"; } }; class Magnificent : public Superb { private: char ch; public: Magnificent(int h = 0, char c = 'A') : Superb(h), ch(c) {} void Speak() const { cout << "I am a magnificent class!!!n"; } void Say() const { cout << "I hold the character " << ch << " and the integer " << Value() << "!n"; } }; Grand * GetOne(); int main() { std::srand(std::time(0)); Grand * pg; Superb * ps; for (int i = 0; i < 5; i++) { pg = GetOne(); pg->Speak(); if (ps = dynamic_cast (pg)) ps->Say(); } // std::cin.get(); return 0; } Grand * GetOne() // generate one of three kinds of objects randomly { Grand * p = nullptr; switch (std::rand() % 3) { case 0: p = new Grand(std::rand() % 100); break; case 1: p = new Superb(std::rand() % 100); break; case 2: p = new Magnificent(std::rand() % 100, 'A' + std::rand() % 26); break; } return p; }
执行结果:
I am a grand class! I am a superb class!! I hold the superb value of 50! I am a superb class!! I hold the superb value of 22! I am a magnificent class!!! I hold the character P and the integer 32! I am a superb class!! I hold the superb value of 33!rtti2.cpp
// rtti2.cpp -- using dynamic_cast, typeid, and type_info #include#include #include #include using namespace std; class Grand { private: int hold; public: Grand(int h = 0) : hold(h) {} virtual void Speak() const { cout << "I am a grand class!n"; } virtual int Value() const { return hold; } }; class Superb : public Grand { public: Superb(int h = 0) : Grand(h) {} void Speak() const { cout << "I am a superb class!!n"; } virtual void Say() const { cout << "I hold the superb value of " << Value() << "!n"; } }; class Magnificent : public Superb { private: char ch; public: Magnificent(int h = 0, char cv = 'A') : Superb(h), ch(cv) {} void Speak() const { cout << "I am a magnificent class!!!n"; } void Say() const { cout << "I hold the character " << ch << " and the integer " << Value() << "!n"; } }; Grand * GetOne(); int main() { srand(time(0)); Grand * pg; Superb * ps; for (int i = 0; i < 5; i++) { pg = GetOne(); cout << "Now processing type " << typeid(*pg).name() << ".n"; pg->Speak(); if (ps = dynamic_cast (pg)) ps->Say(); if (typeid(Magnificent) == typeid(*pg)) cout << "Yes, you're really magnificent.n"; } // std::cin.get(); return 0; } Grand * GetOne() { //Grand * p; Grand * p = nullptr; switch (rand() % 3) { case 0: p = new Grand(rand() % 100); break; case 1: p = new Superb(rand() % 100); break; case 2: p = new Magnificent(rand() % 100, 'A' + rand() % 26); break; } return p; }
执行结果:
Now processing type class Magnificent. I am a magnificent class!!! I hold the character Y and the integer 75! Yes, you're really magnificent. Now processing type class Magnificent. I am a magnificent class!!! I hold the character D and the integer 68! Yes, you're really magnificent. Now processing type class Grand. I am a grand class! Now processing type class Magnificent. I am a magnificent class!!! I hold the character F and the integer 55! Yes, you're really magnificent. Now processing type class Superb. I am a superb class!! I hold the superb value of 1!constcast.cpp
// constcast.cpp -- using const_cast<> #includeusing std::cout; using std::endl; void change(const int * pt, int n); int main() { int pop1 = 38383; const int pop2 = 2000; cout << "pop1, pop2: " << pop1 << ", " << pop2 << endl; change(&pop1, -103); change(&pop2, -103); cout << "pop1, pop2: " << pop1 << ", " << pop2 << endl; // std::cin.get(); return 0; } void change(const int * pt, int n) { int * pc; pc = const_cast (pt); *pc += n; }
执行结果:
pop1, pop2: 38383, 2000 pop1, pop2: 38280, 2000



