C++第十天笔记2016年02月29日(周一)A.M

1.把子类对象作为父类对象使用:

1.1  前提:继承方式必须公有。

1.2 将子类对象用作父类对象。

1.2.1 将子类对象赋值给父类对象。

1.2.2 将父类引用指向子类对象。(即用派生类对象初始化基类引用)

 1 #include <iostream>
 2 using namespace std;
 3
 4 class Base{
 5 public:
 6     Base(){}
 7     Base(int b):_b(b){}
 8     void func(){cout<<"b:"<<_b<<endl;}
 9     Base& fun(Base& b);
10 protected:
11     int _b;
12
13 };
14 class Derived:public Base{
15 public:
16     Derived(){}
17     Derived(int d,int b):_d(d),Base(b){}
18     void func();
19 //    void func(){cout<<"d:"<<_d<<" b:"<<_b<<endl;}
20 protected:
21     int _d;
22 };
23 void Derived::func(){cout<<"d:"<<_d<<" b:"<<_b<<endl;}
24 Base& fun(Base& b){Derived* p=new Derived;return *p;}
25 Base* fun(Base* b){Derived* p=new Derived;return b;}
26
27 int main(int argc, const char * argv[]) {
28
29 //----------------------------------------------------------------------------
30 //----------------------------------------------------------------------------
31 //1.将派生类对象赋值给基类对象。赋值完成后,等号左边的对象,依然是父类对象。
32     Derived d(4,5);
33     Base b;
34     b=d;
35     d.func();
36 //----------------------------------------------------------------------------
37 //----------------------------------------------------------------------------
38 //2.基类引用指派生类
39 //(1).派生类对象用于初始化基类引用。
40 //    Derived d(4,5);
41 //    Base& b=d;
42 //    b.func();
43 //    d.func();
44 //----------------------------------------------------------------------------
45 //----------------------------------------------------------------------------
46 //(2).派生类对象被传递给一个函数,接受基类对象的引用。
47 //    Derived d;
48 //    Base& b=fun(d);
49 //    delete &b;
50 //----------------------------------------------------------------------------
51 //----------------------------------------------------------------------------
52 //(3).派生类从返回类型的函数返回基类引用。
53 //    Derived d;
54 //    Base& b=fun(d);
55 //    delete &b;
56 //----------------------------------------------------------------------------
57 //----------------------------------------------------------------------------
58 //3.基类指针指派生类。
59 //(1).派生类对象的地址分配给基类指针。
60 //    Derived d(1,4);
61 //    Base* b=&d;
62 //    d.func();
63 //    b->func();
64 //----------------------------------------------------------------------------
65 //----------------------------------------------------------------------------
66 //(2).派生类指针被分配给基类指针。
67 //    Derived d(1,4);
68 //    Derived * d2=&d;
69 //    Base* b2=d2;
70 //    b2->func();
71 //----------------------------------------------------------------------------
72 //----------------------------------------------------------------------------
73 //(3).派生类对象的地址传递给接受基类对象的指针的函数。
74 //    Derived d(1,3);
75 //    Base* b=fun(&d);
76 //    b->func();
77 //    delete b;
78 //----------------------------------------------------------------------------
79 //----------------------------------------------------------------------------
80 //当父类指针指向子类对象时,不能通过父类调用子类扩展函数。
81 //另一方面,基类对象不能用作派生类对象。
82     return 0;
83 }

2.  基类指针指向派生类

3.  向下类型转换:将基类的指针或者引用转化为派生类的指针和引用。

实现形式:强转。

目的:通过基类指针或者引用访问到派生类的成员

Point* p=&c;//指针p”指向”的对象”真实身份”为派生类

Point& q=c;//基类引用q”指向”的对象”真实身份”为派生类。

((Circle*)p)->print();

((Circle&)p).print();//向下类需转换

问题:

Point* p=&pp;//pp为基类对象,指针p“指向”的对象“真实身份”基类。((Circle*)p)->print();

有可能出现的问题,输出结果不正确。

向下类型转换不会出现问题:基类指针或者引用“指向”的对象,“真   实身份”为派生类。

 1 //#include <iostream>
 2 //using namespace std;
 3 ////如果一个基类指针指向派生类对象,它可以进行类型转换来访问派生类的成员。这就是所谓的向下转型。然而向下转型是一件危险的做法,因为基类指针可能不实际指向一个对象在派生类,然后程序员任务它是。
 4 //class Base{
 5 //public:
 6 //    Base(){}
 7 //    Base(int _b):b(_b){}
 8 //protected:
 9 //    int b;
10 //};
11 //class Derived:public Base{
12 //public:
13 //    Derived(){}
14 //    Derived(int _d,int _b):d(_d),Base(_b){}
15 //    void func();
16 //protected:
17 //    int d;
18 //};
19 //void Derived::func(){cout<<"d:"<<d<<" b:"<<b<<endl;}
20 //
21 //int main(int argc, const char * argv[]) {
22 //    Derived(3,4);
23 //    Base* b=new Derived;
24 //    //b->func(); //不可以
25 //    ((Derived*)b)->func();//可以
26 //    return 0;
27 //}
28 #include <iostream>
29 using namespace std;
30
31 class Base{
32 public:
33     Base(){}
34     Base(int _b):b(_b){}
35     void func(){cout<<"Base class function..."<<endl;}
36 protected:
37     int b;
38 };
39
40 class Derived:public Base{
41 public:
42     Derived(){}
43     Derived(int _d,int _b):d(_d),Base(_b){}
44     void func(){cout<<"Derived class function..."<<endl;}
45 protected:
46     int d;
47 };
48
49 void foo(Base& b){b.func();}//Base class function...
50 int main(int argc, const char * argv[]) {
51     Derived d;
52     Base b;
53     Base* p=&d;
54     Base& br=d;
55     b=d;
56     b.func();//Base class function...
57     d.func();//Derived class function...
58     p->func();//Base class function...
59     foo(br);
60     br.func();//Base class function...
61     return 0;
62 }

子类构造:

Base声明:

#include <stdio.h>
#include "iostream"
#include "cstring"
using namespace std;
class Base{
public:
    Base(int a=0,char* s=(char*)""):id(a) {
        if (!s) {
            name=NULL;
        }else{
            name=new char[strlen(s)+1];
            strcpy(name, s);
        }
        cout<<"基类默认构造函数"<<endl;
    }
    Base(Base& b){
        id=b.id;
        if (!b.name) {
            delete [] name;
            name=NULL;
        }
        else{
            name=new char[strlen(b.name)+1];
            strcpy(name, b.name);
        }
        cout<<"基类拷贝构造"<<endl;
    }
    ~Base(){
        if (name!=NULL) {
            delete [] name;
            name=NULL;
        }
        cout<<"基类析构"<<endl;
    }
    Base& operator=(Base&);
    friend ostream& operator<<(ostream& out,Base&);
protected:
    int id;
    char* name;
};

Base实现:

 1 #include "Base.hpp"
 2 Base& Base::operator=(Base& b){
 3     if (this!=&b) {
 4         id=b.id;
 5         delete [] name;
 6         if (!b.name) {
 7             name=NULL;
 8         }else{
 9             name=new char[strlen(b.name)+1];
10             strcpy(name, b.name);
11         }
12     }
13     cout<<"基类赋值重载"<<endl;
14     return *this;
15 }
16 ostream& operator<<(ostream& out,Base& b){
17     out<<"Base id:"<<b.id<<endl;
18     return out;
19 }

Derived声明:

 1 #include <stdio.h>
 2 #include "Base.hpp"
 3 #include "cstring"
 4 #include "iostream"
 5 using namespace std;
 6 class Derived:public Base{
 7 public:
 8     Derived(int a=0,char* s=(char*)"",float x=0,char* t=(char*)""):Base(a,s),f(x){
 9         if (!t) {
10             label=NULL;
11         }else{
12             label=new char[strlen(t)+1];
13             strcpy(label, t);
14         }
15         cout<<"派生类拷贝构造"<<endl;
16     }
17     ~Derived(){
18 //        delete [] label;
19         cout<<"派生类析构"<<endl;
20     }
21     Derived& operator=(Derived&);
22     friend ostream& operator<<(ostream& out,Derived&);
23 private:
24     float f;
25     char* label;
26 };

Derived实现:

 1 #include "Derived.hpp"
 2 Derived& Derived::operator=(Derived& d){
 3     if (this!=&d) {
 4         delete [] label;
 5         label=NULL;
 6         Base::operator=(d);
 7         f=d.f;
 8         if (!d.label) {
 9             label=NULL;
10         }else{
11             label=new char[strlen(d.label)+1];
12             strcpy(label, d.label);
13         }
14         cout<<"派生类赋值重载"<<endl;
15     }
16     return *this;
17 }
18 ostream& operator<<(ostream& out,Derived& d){
19     out<<(Base&)d;
20     out<<"Derived f:"<<d.f<<endl;
21     out<<"Derived label:"<<d.label<<endl;
22     return out;
23 }

main函数:

 1 #include <iostream>
 2 #include "Base.hpp"
 3 #include "Derived.hpp"
 4 using namespace std;
 5
 6 int main(int argc, const char * argv[]) {
 7
 8     Derived d1;
 9     Derived d2(d1);
10     return 0;
11 }
时间: 2024-08-05 19:32:01

C++第十天笔记2016年02月29日(周一)A.M的相关文章

C++第七天笔记2016年02月24日(周三)A.M

1.    拷贝构造函数:也是构造函数. 2.    拷贝构造的作用: (1). 用一个已经存在的对象创建并初始化新对象. 1 object=another_object; //赋值重载 2 Person object=another_object; //拷贝构造函数. 3 Person object(another_object); //开辟堆空间 1 Person obj; 2 Person* p=new Person(obj); //编辑器会调用拷贝构造函数. delete p; 3. 

C++第六天笔记2016年02月23日(周二)A.M

1.    赋值运算符的重载: 什么情况下需要赋值运算符的重载? 当类中有指向对空间的指针变量时,需要重载赋值运算符以实现深拷贝. 浅拷贝问题: 当类中有指向对空间的指针变量时,前拷贝有可能会导致二次删除或内存泄露问题. 重载赋值操作符分5步:a=a; 1.1  判断是否为自赋值à自赋值则直接跳至第5步. 1.2  删除旧的堆空间(指针指向的旧的堆空间) 1.3  申请新的堆空间 1.4  内容拷贝 1.5  return* this; 浅拷贝: 1 #include <iostream> 2

C++第五天笔记2016年02月22日(周一)P.M

1.    输出运算符重载: 1 #include <iostream> 2 #include"cstring" 3 4 using namespace std; 5 6 class Complex 7 { 8 public: 9 Complex(int r=0,int i=0):_r(r),_i(i){} 10 void print(); 11 friend ostream& operator<<(ostream& out,const Comp

C++第八天笔记2016年02月25日(周四)A.M

1.    继承:一个类A可以继承另一个类B,那么我们称类B为基类(父类),类A为派生类 (子类). 2.    派生类从基类继承了所有成员,除了构造函数.析构函数.=函数. 3.    基类的私有成员,虽然它们也是派生类的私有成员,但是不能在派生类中定义的成员函数访问.这些基类的私有成员只能通过基类的公有成员函数访问. 4.    子类可以自己实现与父类成员函数原型相同(函数名.参数列表)的成员函数,称为覆盖.覆盖是函数重载的特例,覆盖一定是发生在继承的过程中. 在子类中调用被覆盖的父类版本的

C++第七天笔记2016年02月24日(周三)P.M

1.    哪些构造函数支持做类型转换? 传递一个参数就可以被调用的构造函数. 2.    不同函数调用时间分析源码: 1 #include <iostream> 2 using namespace std; 3 4 class Demo{ 5 public: 6 Demo(int n=0):i(n){cout<<"默认构造函数被调用"<<endl;} 7 Demo(const Demo& a) 8 { 9 i=a.i; 10 cout<

C++第四天笔记2016年01月29日(周五)A.M

1.   类的静态成员 静态局部变量: (1)    静态局部变量的空间并非在栈区. (2)    静态局部变量可以保留上一次函数调用时的计算结果,这与全局变量很相似,但是静态局部变量只能在当前函数体内可见. (3)    静态局部变量如果未进行初始化,会被编译器初始化为0. 静态变量的声明只会执行一次,以保证static静态变量只有一块空间 静态成员变量的初始化放在类定义之外单独做初始化,基本格式:类型 类名: : 静态成员变量名 例: int Employee::next_id = 0;//

软考信息系统监理师:2016年4月29日作业

软考信息系统监理师:2016年4月29日作业一.信息应用系统分析设计阶段监理1.需求分析的进入条件是什么?(记)2.需求分析的目标是什么?3.需求分析阶段的成果有哪些?(记)4.软件概要设计阶段的进入条件是什么?(记,并理解:加不加概要2字,答案均相同)5.软件详细设计阶段的进入条件是什么?6.描述算法除了流程图外,还有一些别的工具,如哪3种?7.软件设计阶段的成果是什么?(记)8.软件工程化要求以软件质量保证为核心,紧紧抓住哪8个主要环节?二.信息应用系统实施阶段监理1.编码阶段进入条件是什么

2016年04月29日【EPM-易通元】最新价位公布

2016年04月29日[EPM-易通元]最新价位公布   涨了.涨了.又涨了!   我们的「EPM易通元」天天见涨!太给力了!!   2016.04.29日今天已涨0,01美金,目前已到0.35美金啦!   如果你有1000个易通元,你今天就收益10美金   如果你有10000个易通元,今天就收益100美金   如果你有100000个易通元,你今天就收益1000美金.   恭喜买到「EPM易通元」的朋友们,买到即是赚到!   买入210美金到3500美金 :1美金:6.3人民币兑换,举例买入35

20.5 语音合成(百度2016年2月29日发布的tts引擎)

分类:C#.Android.VS2015: 创建日期:2016-03-17 一.简介 编写手机App时,有时需要使用文字转语音(Text to Speech)的功能,比如开车时阅读收到的短信.导航语音提示.界面中比较重要的信息通过语音强调.--等. 由于Android自带的Pico TTS并不支持中文,所以要既能阅读中文文本,还能阅读英文文本,必须下载第三方提供的能说中文的语音包. 二.申请百度tts授权 本节以百度2016年2月29日发布的"离在线融合语音合成SDK_Android 2.2.3