继承与派生

(一)派生类对象的内存空间

1.派生类对象的体积,等于基类对象的体积,再加上派生类对象自己的成员变量的体积。在派生类对象中,包含着基类对象,而且基类对象的存储位置位于派生类对象新增的成员变量之前。

2.对象存储顺序,v1,v2,v3。

class CBase{
  int v1,v2;
};
class CDerived:public CBase{
   int v3;
}

3.示例代码(涉及String类)

#include <iostream>
#include <string>
using namespace std;
class CStudent
{
private:
    string name;
    string id; //学号
    char gender;//性别,'F'代表女,'M'代表男
    int age;
public:
    void PrintInfo();
    void SetInfo( const string & name_,const string & id_,int age_, char gender_ );
    string GetName() { return name; }
};

class CUndergraduateStudent:public CStudent 
{//本科生类,继承了CStudent类
private:
    string department; //学生所属的系的名称
public:
    void QualifiedForBaoyan() { //给予保研资格
        cout << "qualified for baoyan" << endl;
}
    void PrintInfo() {
        CStudent::PrintInfo(); //调用基类的PrintInfo
        cout << "Department:" << department <<endl;
    }
    void SetInfo(const string & name_,const string & id_,
        int age_,char gender_ ,const string & department_) {
        CStudent::SetInfo(name_,id_,age_,gender_); //调用基类的SetInfo
        department = department_;
    }
};
void CStudent::PrintInfo()
{
    cout << "Name:" << name << endl;
    cout << "ID:" << id << endl;
    cout << "Age:" << age << endl;
    cout << "Gender:" << gender << endl;
}
void CStudent::SetInfo(const string & name_,const string & id_, 
                       int age_,char gender_ )
{
    name = name_;
    id = id_;
    age = age_;
    gender = gender_;
}
int main()
{
    CUndergraduateStudent s2;
    s2.SetInfo("Harry Potter ", "118829212",19,'M',"Computer Science");
    cout << s2.GetName() <<" " ;
    s2.QualifiedForBaoyan ();
    s2.PrintInfo ();
    return 0;
}
//输出:
//Harry Potter qualified for baoyanName:Harry Potter
//ID:118829212
//Age:19Gender:M
//Department:Computer Science

补充:

(1)String对象的初始化:

  – string s1("Hello"); – string month = "March"; – string s2(8,’x’);//xxxxxxxx

(2)可以将字符赋值给string对象
  – string s;– s = ‘n’;

(3)输入String的方式:

  cin >> stringObject; getline(cin ,s); 

(4)赋值方式

string s1("cat"), s2; 
s2 = s1;  
string s1("cat"), s3; 
s3.assign(s1);
string s1("catpig"), s3;  
s3.assign(s1, 1, 3);  //从s1中下标为1的字符开始复制3个字符给s3

(5)取单个字符的方式

for(int i=0;i<s1.length();i++)
    cout << s1.at(i) << endl;
//成员函数at会做范围检查,如果超出范围,会抛出out_of_range异常,而下标运算符[]不做范围检查。

(6)String相连

  1)string s1("good "), s2("morning! ");s1 += s2;cout << s;

  2) 用成员函数 append 连接字符串

string s1("good "), s2("morning! ");
s1.append(s2);cout << s1;
s2.append(s1, 3, s1.size());//s1.size(),s1字符数
cout << s2;
// 从s1的下标3开始的s1.size()个字符添加到s2中,如果s1字符串内没有足够字符,则复
制到字符串最后一个字符

  (7)比较字符串String。

     1)用关系运算符比较string的大小,关系运算符包括:== , >, >=, <, <=,成立则返回true,否则返回false。

          例如:

string s1("hello"),s2("hello"),s3("hell");
bool b = (s1 == s2); 
cout << b << endl;//输出1。
b = (s1 == s3); 
cout << b << endl;//输出0。
b = (s1 > s3); 
cout << b << endl;//输出1。

      2)用成员函数compare比较string的大小

string s1("hello"),s2("hello"),s3("hell");
int f1 = s1.compare(s2);
int f2 = s1.compare(s3);
int f3 = s3.compare(s1);
int f4 = s1.compare(1,2,s3,0,3); //s1 1-2; s3 0-3
int f5 = s1.compare(0,s1.size(),s3);//s1 0-end
cout << f1 << endl << f2 << endl << f3 << endl; 
cout << f4 << endl << f5 << endl; 
//输出 0 1 -1 -1 1。

     3)成员函数substr取子串。

string s1("hello world"), s2;
s2 = s1.substr(4,5); // 下标4开始5个字符
cout << s2 << endl;  //输出:o wor

     4)成员函数swap交换子串。

string s1("hello world"), s2("really");
s1.swap(s2); 
cout << s1 << endl;
cout << s2 << endl;
//输出:really
//     hello world

     5)寻找String中的字符

string s1("hello world");
s1.find("lo");
//在s1中从前向后查找 “lo” 第一次出现的地方,如果找到,返回 “lo”开始的位置,即 l 所在的位置下标。如果找不到,返回string::npos (string中定义的静态常量)
string s1("hello world");
s1.rfind("lo");
//在s1中从后向前查找 “lo” 第一次出现的地方,如果找到,返回 “lo”开始的位置,即 l 所在的位置下标。如果找不到,返回string::npos

p17略。

     6)删除String中的字符串。

string s1("hello worlld");
s1.erase(5);
cout << s1<<" ";
cout << s1.length()<<" ";
cout << s1.size();
// 去掉下标 5 及之后的字符
//输出:hello 5 5

     7)替换String中的字符串。

string s1("hello world");
s1.replace(2,3, "haha", 1,2);
cout << s1;
// 将s1中下标2开始的3个字符换成“haha” 中下标1开始的2个字符
// 输出:heah world

    8)在String中插入字符。

string s1("hello world"); 
string s2(“show insert");
s1.insert(5,s2); // 将s2插入s1下标5的位置
cout << s1 << endl;
s1.insert(2,s2,5,3); 
//将s2中下标5开始的3个字符插入s1下标2的位置
cout << s1 << endl;
//输出:
//helloshow insert world
//heinslloshow insert world

     9)字符串拷贝copy()。

string s1("hello world");
int len = s1.length();
char * p2 = new char[len+1];
s1.copy(p2,5,0); 
p2[5]=0;
cout << p2 << endl;
// s1.copy(p2,5,0) 从s1的下标0的字符开始制作一个最长5个字符长度的字符串副本并将其赋值给p2。返回值表明实际复制字符串的长度。
//输出:hello

     10)字符串流处理

//字符串流处理 - 字符串输入流 
istringstreamstring input("Input test 123 4.7 A");
istringstream inputString(input);
string string1, string2;
int i;double d;
char cinputString >> string1 >> string2 >> i >> d >> c;
cout << string1 << endl << string2 << endl;
cout << i << endl << d << endl << c <<endl;long L;
if(inputString >> L) cout << "long\n";else cout << "empty\n";
//输出:Inputtest1234.7Aempty字符串流处理 - 字符串输出流 istringstreamostringstream outputString;int a = 10;
outputString << "This " << a << "ok" << endl;
cout << outputString.str();
//输出:This 10

4.类之间的两种关系:继承和复合。

(1)复合关系的使用

//复合关系的使用
//正确的写法:为“狗”类设一个“业主”类的对象指针;为“业主”类设一个“狗”类的对象指针组。
class CMaster; 
//CMaster必须提前声明,不能先写CMaster类后写Cdog类
class CDog {
  CMaster * pm;
};
class CMaster {
  CDog * dogs[10];
}; 

(2)基类和派生类有同名成员的情况:用这种格式base::i标明是基类的对象而不是派生类的对象。

5.派生类的构造函数

      在创建派生类的对象时,需要调用基类的构造函数:初始化派生类对象中从基类继承的成员。//在执行一个派生类的构造函数之前,总是先执行基类的构造函数。
     调用基类构造函数的两种方式
    (1)显式方式:在派生类的构造函数中,为基类的构造函数提供参数.
            derived::derived(arg_derived-list):base(arg_base-list);
        包含成员对象的派生类的构造函数:

class Skill {
    public:Skill(int n) { }
};
class FlyBug: public Bug {
    int nWings;
    Skill sk1, sk2;
public:
    FlyBug( int legs, int color, int wings);
};
FlyBug::FlyBug( int legs, int color, int wings):      
                Bug(legs,color),sk1(5),sk2(color) ,nWings(wings) {
} 


    (2)隐式方式:在派生类的构造函数中,省略基类构造函数时,派生类的构造函数则自动调用基类的默认构造函数.

        派生类的析构函数被执行时,执行完派生类的析构函数后,自动调用基类的析构函数。

//未结束待补充。

 


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值