(二)C++头文件与类的声明

目录

一、C vs C++,关于数据和函数

二、class分类

2.1 complex(经典不带指针--复数)

 2.2 string(经典带指针--字符串)

三、Object Based(基于对象)vs Object Oriented(面向对象)

四、C++ programs代码基本形式

五、Output(输出区别),C++ vs C

六、Header(头文件)当中的防卫式声明与布局

6.1 guard(防卫式声明)

6.2 Header(头文件)的布局

6.1.1 class 的声明(declaration)

6.1.2 class template(模板)简介


一、C vs C++,关于数据和函数

        在C语言中,设计程序时,需要准备数据Data与函数Functions,函数是用来处理数据,那么这个数据Data会有很多类型(built-in内置、struct结构体),Data数据根据类型创建许多真值数据variables。这样的缺点是由于语言没有提供足够的关键字,variables数据一定是全局的,对于所有Functions都可以处理variables,对后续有影响。

        于是发展到了C++面向对象的语言中,将数据Date Membres与Members Function进行绑定,称为class,相当于C中的struct结构体,但是多了很多新特性,即只有对应的Members Function函数可以处理Data Members数据,优点是不会进行混杂。Data Membres与Members Function绑定后,根据这些class,以这种形式,创建了很多的objects(对象),在objects中进行处理。

(二)C++头文件与类的声明_第1张图片

二、class分类

        在上一章中我们说,最经典的class分类为不带指针的与带指针的,这里面最经典的两个分别是complex(复数)与string(字符串)。

(二)C++头文件与类的声明_第2张图片

2.1 complex(经典不带指针--复数)

        complex有实部与虚部之分,那么根据complex创建出来的c1、c2……中每个都含有实部与虚部,这就是在内存中占用的大小。在设计复数中还需要设计包含黄色的Functions,来处理c1、c2……,即一类函数处理多个数据。

        complex中把Date与Functions包含在一起,说数据有很多个但函数只有一类,这个原因会在后面讲到。

complex c1(2,1);
complex c2;
complex* pc = new complex(0,1);

 2.2 string(经典带指针--字符串)

        特别在于,对“Hello World”这类字符串,实际上其中只有一根指针(ptr),那么ptr要在内存中指出这个字符串,这个字符串(内容、即"Hello World")在另外设计这个类的内存中,分配空间存储这个字符串(内容)。

        所以创建出来的s1、s2……,这些字符串所占用的内存大小中,实际上只有一个ptr。

string s1("Hello");
string s2("World");
string* ps = new string;

代码中创建方式是不同的,后续会说到

三、Object Based(基于对象)vs Object Oriented(面向对象)

Object Based:面对的是单一class的设计

        omplex(复数)--Class without pointer member(s))

Object Oriented:面对的是多重classes的设计,classes和classes之间的联系。

        string(字符串)--Class with pointer member(s)

四、C++ programs代码基本形式

(二)C++头文件与类的声明_第3张图片

        在一个C++ programs中,包含一个头文件、主程序、标准库(当然这么分并不是很准确但可以这里理解)。

        主程序使用头文件,使用include"---",使用标准库,使用include<--->。头文件和标准库都为.h文件,对声明和标准库的区别就是双引号和尖括号的区别。

        对于文件名,或者说延伸的文件名(extension file name)可能不会是.h / .cpp的后缀,可能是.hpp或其他的,甚至无延伸的文件名。

五、Output(输出区别),C++ vs C

        在C 中使用#include或者#include

#include 

int main()
{
    int i = 7;
    printf("i=%d \n" , i);
    return 0;
}

        在C++中有更好的方法,#include 或者#include ,输出中cout使用的更加自然

#include 
using namespace std;

int main()
{
    int i = 7;
    cout << "i=" << i << endl;
    return 0;
}

六、Header(头文件)当中的防卫式声明与布局

6.1 guard(防卫式声明)

        对complex.h中,有严格的头文件写法,我们说很多程序要用到这个声明文件,或者说自己用到,那么include中为了忽略次序引用,所以说写一个guard(防卫式声明)。第二次进行include时不会做多余的动作。

        (程序内容不做详细说明,只说COMPLEX是自己定义的)

#ifndef __COMPLEX__
#difine __COMPLEX__

------------------
-                -
-                -
-                -
-······          -
-                -
-                -
------------------

#endif

        那么在下列的以complex-test.h中,实际上对复数进行的操作,就是中间主体部分,即“--------”之间的内容。

#include 
#include "complex.h"
using namespace std;

int main()
{
    complex c1(2,1);
    complex c2;
    cout << c1 << endl;
    cout << c2 << endl;
    
    c2 = c1 + 5;
    c2 = 7 + c1;
    c2 = c1 + c2;
    .......
    
    return 0;
}

6.2 Header(头文件)的布局

在一个基本的complex.h中,具体是以下布局

其中开始的第一段“--------”到“-----------”为forward declarations(前置声明)

第二段中为class declarations(类-声明)重要

第三段中为class definition(类-定义)重要

#ifndef __COMPLEX__
#difine __COMPLEX__

----------------------------------------------------
#include 

class ostream;
class complex;

complex&
    __doapl (complex* ths, const complex& r);
---------------------------------------------------

---------------------------------------------------
class complex
{
.......
};
---------------------------------------------------

---------------------------------------------------
complex::function...
---------------------------------------------------

#endif

6.1.1 class 的声明(declaration)

class complex
{
public:
    explicit complex(double r = 0,double i = 0)
    : re (r), im (i)
    {    }
    complex& operator += (const complex&);
    double real () const { return re;}
    double imag () const {return im;}

private:
    double re , im;
    
    friend complex& __doapl (complex* , const complex&);
};

        在下列程序中,任何一个class都有class hand,在下方中第一个“ {  } ”中为class body。在class body中设计complex应该是什么样的数据,是怎么样的函数,来满足使用要求。

private:
    double re , im;

        这里是Data,上面就是就是Data的函数,后续讲到。friend为在设计另一类、单元、函数与现在的关系。

6.1.2 class template(模板)简介

        在复数中最重要的是里面该有什么样的信息,即有实部与虚部,代码中为double re , im;

即实部re,虚部im都为double值,假如设计为浮点数,整数,那么需要再写一个class complex 将private:部分的double改为float/int,其余同理,只是类型不同而已。所以这里引出一个模板

        这里我们不将数据实部虚部类型写死,而是T(只是一个符号)类,告诉编译器,类型未定,则第一行写template,为一个typename。

template
class complex
{
public:
    explicit complex(double r = 0,double i = 0)
    : re (r), im (i)
    {    }
    complex& operator += (const complex&);
    double real () const { return re;}
    double imag () const {return im;}

private:
    T re , im;
    
    friend complex& __doapl (complex* , const complex&);
};

        那么使用的时候再指定,写法如下:

{
    complex c1(2.5 , 1.5);
    complex c2(2 , 6);
    ……
}

        但我们在后续写的时候依旧不会用到模板。


下一章:(三)C++构造函数

你可能感兴趣的:(C++,c++,架构)