C++补全计划1

这里是C++补全计划,学习Qt 的过程中时,发现C++必须回顾一番


书籍名称:C++ PLUS

前期补充:

关于 using namespace std 的一些注意:、

是用来创建一个名称空间使得函数可以去访问。

让程序访问名称空间std的方法有四种

1.将using namespace std放在函数定义的前面,让文件的所有函数可以使用名称空间std中所有元素。

2.将using namespace std放在特定的函数定义中,让函数可以使用名称空间中所有元素。

3.在特定函数中使用类似using std::cout这样的编译指令,而不是using namespace std,让该函数能够使用特定元素,如cout

4.完全不使用using,而在需要使用名称空间std中的元素时,使用前缀std::。

 

关于namespace的一些资料总结:

为了避免词汇的重复而引发的错误,因此需要一个stdnamespace的库,里面包含了无数的标准函数。使用的时候就像是全局声明一样。

 

 

 

 

#ifdef

程序段1

#else

程序段2

#endif

它的作用是:当标识符已经被定义过(一般是用#define命令定义),则对程序段1进行编译,否则编译程序段2

 

&除了用来指示变量地址,还赋予了用来声明引用。

如:int rate

Int & rodents = rats

&是类型标识符,这里是指向int的引用。

引用和指针还是有一些差别的,在声明的时候引用要将其初始化,而不能像指针那样,先声明再赋值。

函数调用参数时,在变量前追加上地址符号,或者指针,只有这样才能使用到之前赋值给变量里面的值。

产生临时变量的两种情况:

实参的类型正确,但不是左值;

实参的类型不正确,但是可以转换为正确的类型。

左值:可以被引用的数据对象。

应该尽可能使用const:可以避免无意中修改数据的变成错误,使函数能够处理const和非const,否则只能接受非const;使函数能够正确生成并且使用临时变量。

 

引用十分适合结构和类

使用结构引用参数的方式与使用基本变量引用相同,只需要在声明结构参数时候使用引用运算符&即可。

Void se_pc(free_thows & ft); 在函数中将指向该结构的引用作为参数。

 

 

 

第十章:

对象和类

OOP的特性:抽象,封装和数据隐藏,多态,继承,代码重用性

指定基本类完成的三项工作:决定数据对象需要的内存数量,决定如何解释内存的位,决定可使用数据对象执行的操作或方法。

类是一种将抽象转换为用户定义类型的C++工具,它将数据表示和操作的方法组成一个整洁的包。

类两部分组成:

类的声明

类方法的定义

 

开发一个类并编写一个使用它的程序需要许多步骤:通常,将接口(类定义)放在头文件中,并将实现(类方法的代码)放在源代码文件中。

为了识别类,本书遵循一种常见单不常通用的约定,将类名首字母大写。看起来像一个结构声明。

使用类的对象:class socket{};

Stock sally

Stock solly

 

关键字privatepublic描述了对类成员的访问控制。使用类对象的程序都可以直接访问公有部分,但只能通过公有成员(友元函数)来访问对象的私有成员。

  通常,程序员使用私有成员来处理不输于公有接口的实现细节。

实现类成员函数

  数据自动的带有private属性

  (::)作用域解析运算符来标示函数所属的类。

  类方法可以访问private组件

 Void stock::update(double price)

  Stock类的其他成员函数不必使用作用域解析运算符,就可以使用update()

类方法的完整名称:函数的限定名。还有简单的update()是全名的缩写,它只能在类作用域里面使用。

 

内联函数:定义位于声明中的函数都将自动成为内联函数。

修改实现:修改方法实现时,不能影响客户程序的其他部分。

避免科学计数法:

Std::cout.setf(std::ios_base,std::ios_base::floafield)

创建对象,只需要将类名视为类型名:Bozo bozetta

调用:cout<<Bozetta.Retort();

 

类的构造函数和析构函数

为了违背数据隐藏的初衷,还要将类对象初始化,最好在创建对象的时候进行初始化:

Stock gift;

Gift.buy(10,24.25);

但是办不到,不可能什么时候都有这种情况。

为此出现了类构造函数。

 

构造函数的参数表示的不是类成员,而是赋给类成员的值。

C++提供了两种使用构造函数来初始化对象的方法。第一种是显式地调用构造函数,

Stock food=Stock(“....”,250,1.25);

另一种是隐式的调用构造函数:

Stock garment=Stock(“....”,50,2.5)

每次创建类对象时,使用new动态分配内存:

Stock *pstock=new Stock(“”,18,19.0)

调用构造函数是用对象来调用

 

析构函数:用来释放构造函数占用的内存。

原型:~Stock();

 

 

Stock1=stock(“”,10,2.5);

Stock1对象已经存在,因此并不是对着stock1初始化,而是将新值赋予它。

Void stock::show() const

以这种方式声明和定义的类函数被称为const成员函数。只要类方法不修改调用对象,应将其声明为const

函数:const stock & stock::topval(const stock & s) const

This:就是对函数的简写,也就是this->topval()

同时this被限定为const,就不能修改对象的值

 

9

程序分为3部分

头文件,源文件,源代码

编译器只要检查到#ifdenf #define定义了之后,就会直接跳到#endif上一行运行。

 

 

 

 

作用域:描述了名称在文件的多大范围可见。

自动变量的作用域为局部。静态变量的作用域是局部还是全局取决于是如何被定义的。

在函数原型作用域中适应的名称只在包含参数列表的括号内可用。

类声明成员的作用域为整个类。

名称空间中声明的变量只有整个名称空间。

 

用new和C++ delete可以动态开辟,撤销地址空间.在编程序时,若用完一个变量(一般是暂时存储的数组),下次需要再用,但却又想省去重新初始化的功夫,可以在每次开始使用时开辟一个空间,在用完后撤销它.

 

简单地说,那些被virtual关键字修饰的成员函数,就是虚函数。虚函数的作用,用专业术语来解释就是实现多态性Polymorphism),多态性是将接口与实现进行分离;用形象的语言来解释就是实现以共同的方法,但因个体差异,而采用不同的策略。下面来看一段简单的代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

#include<iostream>

using namespace std;

class A

{

    public:

        void print()

        {

            cout<<"This is A"<<endl;

        }

};

 

class B : public A

{

    public:

        void print()

        {

            cout<<"This is B"<<endl;

        }

};

 

int main()

{

    //为了在以后便于区分,我这段main()代码叫做main1

    A a;

    B b;

    a.print();

    b.print();

    return 0;

}

输出结果

分别是“ThisisA”“ThisisB”。通过class Aclass Bprint()这个接口,可以看出这两个class因个体的差异而采用了不同的策略,但这是否真正做到了多态性呢?No,多态还有个关键之处就是一切用指向基类指针或引用来操作对象。那现在就把main()处的代码改一改。

1

2

3

4

5

6

7

8

9

10

11

int main()

{

    //main2

    A a;

    B b;

    A *p1 = &a;

    A *p2 = &b;

    p1->print();

    p2->print();

    return 0;

}

运行一下看看结果,哟呵,蓦然回首,结果却是两个This is A。问题来了,p2明明指向的是class B的对象但却是调用的class Aprint()函数,这不是我们所期望的结果,那么解决这个问题就需要用到虚函数

1

2

3

4

5

6

7

8

9

10

class A

{

    public:

        virtual void print(){cout<<"This is A"<<endl;}

};

class B : public A

{

    public:

    void print(){cout<<"ThisisB"<<endl;}

};

毫无疑问,class A成员函数print()已经成了虚函数,那么class Bprint()成了虚函数了吗?回答是Yes,我们只需在把基类的成员函数设为virtual,其派生类的相应的函数也会自动变为虚函数。所以,class Bprint()也成了虚函数。那么对于在派生类的相应函数前是否需要用virtual关键字修饰,那就是你自己的问题了(语法上可加可不加,不加的话编译器会自动加上,但为了阅读方便和规范性,建议加上)。

现在重新运行main2的代码,这样输出的结果就是This is AThis is B了。

现在来消化一下,我作个简单的总结,指向基类指针在操作它的多态类对象时,会根据不同的类对象,调用其相应的函数,这个函数就是虚函数。

 


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值