0_

来源:互联网 发布:mac窗口缩小快捷键 编辑:程序博客网 时间:2024/06/03 07:34

这个排版太难了,就没牌了。在百度网盘c++笔记中自己找

一、 C++ 2
1、 C++的头文件 2
2、 命名空间 2
3、 更严格的类型转化 2
4、 new和delete 2
5、 内联函数 2
6、 引用 2
7、 函数的重载 3
8、 函数模板(后面还会讲class模板) 3
二、 类和对象 4
1、 C++类成员的保护 4
2、 C++类的本质 4
3、 类的作用域 4
4、 类的构造和析构函数 4
5、 构造函数的初始化成员列表 5
6、 拷贝构造函数 5
7、 常量类成员,常量对象。 5
8、 explicit 6
9、 this指针 6
10、 类的static成员变量 6
三、 C++封装与移植训练 7
1、 UDP协议 7
2、 C和C++混合编程(在C++中调用自己的c函数) 8
3、 makefile 9
四、 拷贝构造复习 11
1、 拷贝构造函数: 11
2、 以下情况都会调用拷贝构造函数: 11
3、 传参: 11
五、 友元机制 12
1、 友元定义: 12
2、 友元函数 12
3、 友元类 12
4、 注意: 12
5、 12
六、 操作符重载 13
1、 重载定义: 13
2、 不能重载的操作符: 13
3、 重载规则 13
4、 成员函数的语法形式为: 13
5、 几种情况(具体看overload.cpp) 13
6、 二元与一元重载 13

一、C++
1、C++的头文件
①.传统的C头文件,

Eg : <stdio.h>

②.C++头文件

Eg : <iostream> 

③.hpp文件件

Eg : <happy.hpp>

2、命名空间
①.C++引入了新的概念,命名空间可以有效避免大型项目中的各种名称冲突
②.class关键字
③.class是C++的核心,是面向对象编程的核心内容
3、更严格的类型转化
①.在C++,不同类型的指针是不能直接赋值的,必须强转

Eg :   void *p ;      int *a = (void *)p ;(这是C语言风格的类型强制转换)

4、new和delete
①.new和delete是C++内建的操作符,不需要有任何头文件,用new分配的内存必须用delete释放,不要用free。
②.new创建数组的方法new[];
5、内联函数
①.inline关键字的意思是,内联函数不作为函数调用,而是直接把内联函数的代码嵌入到调用的语句中
②.内联函数适合函数代码很少,并且频繁的大量调用。
6、引用
①.引用就是一个变量的别名,而不是地址
②.引用必须在定义的时候就被赋值,(在真实的变量没出来之前怎么会有别名呢)

Eg :   int a = 2 ;   Int &b = a ; (这样可以)   /******************/   Int &b ;   Int a = 2 ;   b = a ;(这样不行) 

③.函数的缺省参数(必须放在后面)

Eg :    void myFunction(int a , int b , int c=2 ) ;(可以)   Void myFunction(int a=2 , int b , int c ) ; (不可以)

④.C++允许函数在定义的时候,提供缺省参数,如果调用函数的时候没有提供形参,那么形参的值就是缺省值
⑤.引用做为函数的参数,没有出栈,入栈操作,所以效率更高
⑥.如果要使引用参数的值不能在函数内部被修改,那么就定义为常量引用 const &

7、函数的重载
①.函数的名称是一样的,但参数不同可以重载
②.函数参数相同,
③.注意:
当函数的缺省参数缺省后系统不知道调用哪个函数时,是不允许的。
8、函数模板(后面还会讲class模板)
①.模板的形式:

Template < typename  T>    通用函数定义或是:   Template < class  T >   通用函数定义Eg :    Template < class T >   T max( T a , T b ){     return a * b ;   }

二、类和对象
1、C++类成员的保护
①.如果类函数返回的是成员变量的指针,为了避免在类外部成员变量被修改,所以函数就要返回常量指针

Eg : const char *  mychen() {      Return “hello” ;    }   Main(){      Char * p = (char *)mychen() ;      P = “work” ;(这通过强转是可以改的)   }

②.如果一个类成员变量和一个全局变量重名,那么在类成员函数当中默认访问的是类的成员变量.
③.在类的内部访问全局标识,关键字 ::
注意:这是在类的外部定义了全局函数或是全局变量,在类的内部采用这种::表示方式。

Eg :     int age = 2 ;    Class a {       Public :         Void getAge(){             ::age = 55 ;(这就是在类的内部访问全局变量)         }    }

2、C++类的本质
①.类其实就是结构的数据成员加可执行代码,统一提供封装,继承,多态。
②.在类内部,没有权限限定符,默认是private
③.在结构内部,没有权限限定符,默认是public
3、类的作用域
①.类成成员变量作用域局限于类内部,类的外部是不可见。
4、类的构造和析构函数
①.构造函数名称和类的名称一致,而且没有返回值
②.一个类实例化为一个对象的时候,自动调用。

class  Chen {   private :   public :       Chen() ;(构造函数)      ~Chen() ;(析构函数,构造函数前面加了~)}

③.一个对象在销毁的时候会自动调用析构函数。
④.默认有构造和析构函数,什么都不做。
5、构造函数的初始化成员列表
①.初始化成员列表只能在构造函数使用
②.const成员必须用初始化成员列表赋值

A.h  namespace  wei {    class  chen{       private :            int  age ;            const  int  face ;       public :            chen() ;(构造函数)    }  } ;A.cpp  namespace  wei {    (构造函数初始化)     Chen ::chen() : age(50).face(55){           age  =  60  ;(这两种初始化方式都是可以的)           face  =  11  ;(不可以,必须通过初始化成员列表赋值)     }  } ;

③.引用数据成员必须用初始化成员列表赋值
④.原则:
由于析构函数只有一个,所以在不同的构造函数里面给函数的成员指针分配内存的时候,一定要统一new或者new[]
6、拷贝构造函数
①.浅拷贝
两个对象之间成员变量简单的赋值。

②.深拷贝
不同的对象指针成员指向不同的内存地址,拷贝构造的时候不是简单的指针赋值,而是将内存拷贝过来。
③.原则:
如果类成员有指针,那么需要自己实现拷贝构造函数,不然存在浅拷
7、常量类成员,常量对象。
①.类成员后面跟关键字const意思是告诉编译器,这个函数内部不会对类成员变量做任何修改。

Eg  :      Void  my()  const {      //(表明这个函数不会对修改类成员)      }

②.函数的参数如果是一个类,那么就用类的引用。如果不想参数被调用函数内部修改,那么就采用const &
8、explicit
①.告诉C++编译器,要明确的调用这个构造函数,而不要自作聪明的认为=操作符是要调用构造的。

Eg  :     class  chen{        private  :            int  age  ;        public   :            explicit  chen(int  age)  ;     }     chen::chen( int  age) {        This->age  =  age ;     }     main{         chen  c  =  2  ; (这样会默认调用构造函数chen(2) , 构造函    数前面加explicit这个关键字,则不可以这样写)     }

9、this指针
①.this就是指向自己实例的指针
10、类的static成员变量
①.static变量是放到静态内存区的,程序加载就存在,一直到程序退出才清理。
②.类的静态成员初始化,

Eg  :    int  chen::age = 55  ;(不可以在类构造函数和初始化成员列表中初                       始化,必须在类外初始化)

③.类的static成员和类的对象没有直接关系,类的静态成员是放到静态内存区的,程序开始执行就存在,一直到程序结束才清理。
④.类的静态成员变量不论类的实例有多少,但成员变量只有一份。
⑤.

三、C++封装与移植训练
(在linux里写的程序直接到window下就能使用,反之需要修改)注意:这里写了一个程序,结合程序会更好理解封装和移植,程序放在同个路径下myudp工程里面。
1、UDP协议
①.TCP/IP
②.UDP协议是基于IP

③.socket把网络协议用C语言封装成一个个函数,放到dll,供其他语言调用,
④.阻塞,一个函数在没有返回之前,程序被挂起.
⑤.recvfrom就是一个阻塞的函数

⑥.网络是字节流,发送是以字节为单位的,如果大于一个字节的数据类型通过网络发送的时候必须调用htons或者htonl函数将数据转化为正确的网络字节流才能发送

windows底层的socket,Ws2_32.lib(socket库)

127.0.0.1,这个IP地址就代表自己。
0,代表自己
255广播
192.168.6.1 192.168.6.254
2、C和C++混合编程(在C++中调用自己的c函数)
①.对于C语言来讲,编译完成之后函数的名称不会改变,对于C++来讲函数的名称发生变化;(所以要用extern “C”)
②.如果是C代码中的函数,在C++中使用一定要用extern “C”关键字来说明;
③.对于操作系统来讲,一定要避免两个程序同时绑定到一个端口。
④.在c++中调用c文件中的函数,如果是提供源文件给其他人调用,则称为混合编程,不过这样别人就可以改变自己的源码。一般不这样用,都是将c文件动态库.so文件给其他人调用。则提供的头文件应该这样写,
Eg:
(假设这里有一个叫a.h的文件,文件里面有个函数max)
#ifndef A_H
#define A_H
extern “C”{
int max(int a , int b ) ; (这是申明)
}
#endif
——->>问题?
——->>既然是动态库,应该是c程序也能调用才对吧,但是c语言
——->>中没有extern “C”这种用法,所以引用这个头文件在c程
——->>序中会报错。
——->>改进。。。。
Eg:
(假设这里有一个叫a.h的文件,文件里面有个函数max)
(__cplusplus宏,如果是c++编译器的话,会自动生成)
#ifndef A_H
#define A_H
#ifdef __cpluscplus (两个下划线)
extern “C”{
#endif
int max(int a , int b ) ; (这是申明)
#ifdef __cpluscplus
}
#endif
#endif

3、makefile
①.gcc编译过程

②.gcc参数
③.-o 指定输出文件名
④.-c 只编译,不链接
⑤.-E预编译
⑥.make是根据.cpp和.o文件的最后修改日期判断cpp文件是否需要编译。如果.o文件不存在,make会失去判断条件,那么一定会编译cpp文件。
⑦.在unix下so文件一定要以lib开头,以so结尾
⑧.gcc参数-iPIC生成和位置无关的代码,

Eg :
CC=g++ (在makefile中变量用大写,定义变量CC)
SRCS=main.cpp\ (\表示换行,工程里的cpp文件多必须换行)
max.cpp
OBJC=$(SRCS:.cpp=.o) (根据cpp文件,写相应的.o文件,:.)
EXEC=main (定义变量EXEC)

target:  $(OBJC)        (开始编写规则:规则名target:依赖项)        $(CC) $(OBJC) -o $(EXEC).cpp.o :                 (表示,根据.cpp文件生成.o文件)        $(CC) -c $< -o $@ ( $@ 依赖项 $< 全部完整文件名)clean :        rm -fr $(EXEC) $(OBJC)

四、拷贝构造复习
1、拷贝构造函数:
wei::wei(const wei &it){
this->age = it.age ;
cout<<”拷贝构造”<