文章目录
1一个筒单的基类
从一个类派生出另一个类时,原始类称为基类,继承类称为派生类。
为说明继承,首先需要一个基类
Webtown俱乐部决定跟踪乒兵球会会员。作为俱乐部的首席程序员,需要设计一个简单的 TableTennisplayer
类,如程序清单13.1和13.2所示。
程序清单13.1 TableTennisPlayer.h
/*
author:梦悦foundation
公众号:梦悦foundation
可以在公众号获得源码和详细的图文笔记
*/
// TableTennisPlayer.h -- a table-tennis base class
#ifndef TABTENN0_H_
#define TABTENN0_H_
#include <string>
using std::string;
// simple base class
class TableTennisPlayer
{
private:
string firstname;
string lastname;
bool hasTable;
public:
TableTennisPlayer (const string & fn = "none",
const string & ln = "none", bool ht = false);
void Name() const;
bool HasTable() const {
return hasTable; };
void ResetTable(bool v) {
hasTable = v; };
};
#endif
程序清单13.2 TableTennisPlayer.cpp
/*
author:梦悦foundation
公众号:梦悦foundation
可以在公众号获得源码和详细的图文笔记
*/
//TableTennisPlayer.cpp -- simple base-class methods
#include "TableTennisPlayer.h"
#include <iostream>
TableTennisPlayer::TableTennisPlayer (const string & fn,
const string & ln, bool ht) : firstname(fn),
lastname(ln), hasTable(ht) {
}
void TableTennisPlayer::Name() const
{
std::cout << lastname << ", " << firstname;
}
TableTennisPlayer类只是记录会员的姓名以及是否有球桌。
有两点需要说明。首先,这个类使用标准 string类来存储姓名,相比于使用字符数组,这更方便、更灵活、更安全,而与第12章的 String类相比,这更专业。其次,构造函数使用了第12章介绍的成员初始化列表语法,但也可以像下面这样做:
TableTennisPlayer::TableTennisPlayer(const string & fn, const string & In, bool ht)
{
firstname = fn;
lastname = ln;
hasTable = ht;
}
这将首先为 firstname调用 string的默认构造函数,再调用 string的赋值运算符将 firstname设置为fn, 但初始化列表语法可减少ー个步骤,它直接使用 string的复制构造函数将 firstname初始化为fn。 -----对这句话存在疑问????
上面这段话,我还是有点疑问的,测试一下,是不是这么个步骤!
这里自己定义了一个 String 类,然后仿照上面 定义了一个 UseString类,这个类里面有一个firstname成员变量,它的构造函数也和上面形式是一样的。为了方便观察,讲很多信息打印出来了。如形参的地址等,好用来分析。
class UseString {
private:
int i;
String firstname;
public:
UseString(const String &firstname) {
cout << "UseString(const String &firstname), this's address:" << this << ", this->firstname address:" << &(this->firstname) << ", &firstname:" << &firstname << endl;
this->firstname = firstname;
}
UseString(const UseString & u) {
cout << "UseString(const UseString & u)" <<endl;
}
#if 0
UseString(const char *u) {
cout << "UseString(const char* u)" <<endl;
}
#endif
};
1. Demo.cpp
/*
author:梦悦foundation
公众号:梦悦foundation
可以在公众号获得源码和详细的图文笔记
*/
#include <iostream>
#include <typeinfo>
#include <string>
#include <cstring>
using namespace std;
class String
{
private:
char * str; // pointer to string
int len; // length of string
static int num_strings; // number of objects
static const int CINLIM = 80; // cin input limit
public:
// constructors and other methods
String(const char * s); // constructor
String(); // default constructor
String(const String &); // copy constructor
~String(); // destructor
int length () const {
return len; }
// overloaded operator methods
String & operator=(const String &);
String & operator=(const char *);
char & operator[](int i);
const char & operator[](int i) const;
// overloaded operator friends
friend bool operator<(const String &st, const String &st2);
friend bool operator>(const String &st1, const String &st2);
friend bool operator==(const String &st, const String &st2);
friend ostream & operator<<(ostream & os, const String & st);
friend istream & operator>>(istream & is, String & st);
// static function
static int HowMany();
};
// initializing static class member
int String::num_strings = 0;
// static method
int String::HowMany()
{
return num_strings;
}
// class methods
String::String(const char * s) // construct String from C string
{
cout << "String(const char * s)" << ", s:" << s << ", this's address:" << this << endl;
len = std::strlen(s); // set size
str = new char[len + 1]; // allot storage
std::strcpy(str, s); // initialize pointer
num_strings++; // set object count
}
String::String() // default constructor
{
cout << "String()" << ", this's address:" << this << endl;
len = 4;
str = new char[1];
str[0]