1 c++扩展语法
1.1 语言链接性---》
C和C++如何实现混合编程?
两种方式:1 在c++工程代码中使用C++和c语言直接实现功能模块
2 自定义的c库函数--》c++代码中使用自定义的c库中函数
extern "C" 函数名;//函数声明 编译C库用C编译器编译
c++代码中要使用C编译器编译的库文件中的函数,在相应的C文件的头文件中
需要声明此函数可以被外部语言调用,即声明C++可以使用该函数。
如何声明?extern "C" 函数头;--》放在库中的对应.h文件中
1.2输入输出
在c++标准库定义了标准输出输入对象,即cout/cin;
cout:console out--->控制台输出
cout是一个输出对象,它在标准命名空间中已经定义了,使用前需要using namespace std;
如何使用?
1 std::cout<<"字符串"<<i<<std::endl;
2 cout<<"字符串\r\n";
cin:console in--->控制台输入
如何使用?
1 cin>>i;
2 cin>>i>>j;
#include <iostream>using namespace std;int main()
{
#if 0cout << "Hello World!" << endl;int i=10;char j='a';//std::cout<<"test:i="<<i<<" j="<<j<<std::endl;// cout<<"hello 21051\r\n";cout<<"i="<<i<<endl;
#endifint a=1;double b=1.2345;char c='h';cout<<"a="<<a<<" b="<<b<<" c="<<c<<endl;
#if 0cin>>a;cin>>b;cin>>c;cout<<"a="<<a<<" b="<<b<<" c="<<c<<endl;
#endifcin>>a>>b>>c;cout<<"a="<<a<<" b="<<b<<" c="<<c<<endl;return 0;
}
2 封装----->包装------->打包
定义:指的是把一类事物的通用属性和操作该属性的方法绑定在一起的一种行为。
c++中封装思想是通过类来体现的。
3 类
定义:是指封装了一类事物的通用属性和操作该属性的方法的一个集合,类是一种复合数据类型,是封装思想的体现。
人:属性+行为
属性---》静态--》变量 char name[];int age;float height;float weiht;
行为---》动态 -->函数 eat();sleep();study();walk();
c阶段:属性----》结构体 struct person zhangsan;---》封装
行为---》函数 eat(zhangsan);sleep();study();walk();
属性和行为如何关联?通过函数的入参将人的属性和行为关联起来。
c++阶段:属性---》结构
行为---》函数
将属性和行为封装在一个闭包中,闭包中的行为就是用来操作属性的
类的定义格式:
struct 结构体名
{
成员1;---》静态
成员2;
。。。。
};----》构造数据类型
class 类名
{
访问限定符:
属性1;--》静态成员---》成员变量
属性2;
。。。
访问限定符:
行为1;---》动态成员---》成员函数
行为2;
};---》构造数据类型
访问限定符:public protected private
public(公有访问限定符):可以被类中的成员函数、子类的函数和其友元函数访问,也可以被该类的对象访问。
protected(保护访问限定符):可以被类中的成员函数、子类的函数和其友元函数访问,但不能被该类的对象访问
private(私有访问限定符):只能由该类中的成员函数和其友元函数访问,不能被子类函数访问,也不能被该类的对象访问
作用:用来约束类中的成员访问权限的
类和结构体的区别?
1 结构体中一般只有成员变量,没有成员函数,并且成员默认是共有的
2 类中一般既有成员变量又有成员函数,在成员变量和成员函数前都有访问限定符,如果没有写访问限定符,则默认该成员是私有的(private)。
4 对象
c++一切皆对象
定义:就是类的实例化
对象的定义格式:(class) 类名 对象名;
对象如何访问它的成员?用"."
对象指针如何访问它指向的对象中的成员?用”->“
注意:类中的成员函数的声明和定义可以一起写,也可以分开写,在类中声明成员函数,在类体外定义该成员函数,定义时需要加上作用域。
?
#include <iostream>using namespace std;class demo
{
public:void setint(int val){ival=val;}void getint(){cout<<"ival="<<ival<<endl;}private:int ival;
};//不占内存空间int main()
{demo obj;//定义一个demo 对象obj.getint();obj.setint(100);obj.getint();//100cout<<"size="<<sizeof(obj)<<endl;//4//cout<<"obj.ival="<<obj.ival<<endl;//类对象不能访问类的私有成员demo *p=&obj;p->setint(500);p->getint();//500return 0;
}?
?
#include <iostream>using namespace std;class demo
{
public:void setint(int val);//声明成员函数void getint();
private:int ival;
};void demo::setint(int val)
{ival=val;
}void demo::getint()
{cout<<"ival="<<ival<<endl;
}class demo1
{
public:void setint(int ival){this->ival=ival;}void getint(){cout<<"ival="<<ival<<endl;}private:int ival;
};int main()
{
#if 0demo obj;obj.setint(300);obj.getint();//300demo &obj1=obj;obj1.setint(600);obj1.getint();
#endifdemo1 obj;obj.setint(300);obj.getint();return 0;
}?
5 this指针
说明:当程序中一个类定义了多个对象,多个对象都调用了同一个成员函数时,怎么区分这个成员函数作用在哪个对象上,c++提供了this指针,this指针在哪?就操作的是哪个对象。
this指针-----》指代当前对象的首地址
*this---->指代当前对象
谁是当前对象?调用成员函数的对象就是当前对象
this指针的使用场合:
1 在类的非静态成员函数中返回类对象本身的时候,直接使用return *this;
2 当类的成员函数的入参名和类中成员变量名相同时,
如:this->ival=ival;(不能写成ival=ival)
6 构造函数
作用:给类对象的成员变量初始化
什么时候调用构造函数?
当用类去创建对象的时候,系统会自动调用对应的构造函数去初始化类对象的成员变量,而且只会调用一次该函数。
特点:
1 是类的成员函数
2 函数名与类名相同
3 无返回值
4 如果一个类没有显示定义构造函数,则系统会自动生成默认的构造函数,默认构造函数无参,函数为空。
5 如果自定义了构造函数,将不会调用默认构造函数,而只会调用自定义的构造函数
6 构造函数无需用户主动调用,在创建对象时,系统自动调用构造函数,而且只会调用一次
7 构造函数可以重载
8 构造函数可以用初始化列表的方式对成员变量进行初始化,或者通过构造函数体内赋值的方式初始化
9构造函数如果定义成非共有,则该构造函数就是限制构造函数,则该类无法创建对象
10 构造函数没有this指针,因为构造函数才是创建对象的,还未创建对象就不会有对象的地址
6.1 普通构造函数
无参构造函数 demo(void)
有参构造函数 demo(int val)
有默认参数的构造函数demo(int val=123)
demo obj;
demo obj1(300);===>demo obj1=300;
demo obj();//error
#include <iostream>using namespace std;
class demo
{
public:demo(int val):ival(val){//ival = val;//函数体内赋值}void getint(){cout << "ival= " << ival << endl;}
private:int ival;
};class demo1
{
public:demo1(int val1,int val2):ival1(val1),ival2(val2){//ival1 = val1;//函数体内赋值//ival2 = val2;}void getint1(){cout << "ival1=" << ival1 << endl;cout << "ival2=" << ival2 << endl;}
private:int ival1;int ival2;
};int main()
{demo obj(100);obj.getint();demo1 obj1(333,666);obj1.getint1();return 0;
}
6.2 默认构造函数
如果类中没有显示定义一个构造函数,编译器会自动提供一个默认构造函数(无参)
6.3 限制构造函数
构造函数非公有,就叫限制构造函数。
如果类中的构造函数是限制构造函数,那么该类无法实例化对象
6.4 拷贝构造函数(复制构造函数)
作用:用一个已经存在的对象给新建对象初始化
6.4.1自定义拷贝构造函数
特点:1 拷贝构造函数没有返回值,函数名与类名相同,一般只有一个参数,而且该参数必须是对象的引用(如果有多个参数,那么除第一个参数外的其他参数只能是默认参数)
2 如果没有显示定义拷贝构造函数,系统会使用默认的拷贝构造函数
3 如果显示定义了拷贝构造函数,就只会使用自定义的
#include <iostream>using namespace std;
class demo
{
public://普通构造函数demo(int val=123){ival=val;cout<<"demo(int val=123)---------\r\n";}//拷贝构造函数demo(demo &obj){ival=obj.ival;cout<<"demo(demo &obj)----------\r\n";}void setint(int val){ival=val;}void getint(){cout<<"ival="<<ival<<endl;}
private:int ival;
};int main()
{demo obj(300);obj.getint();obj.setint(500);obj.getint();//500//demo obj1(obj);demo obj1=obj;obj1.getint();return 0;
}
6.4.2默认拷贝构造函数
如果类中没有显示定义拷贝构造函数,则编译器会提供一个默认的拷贝构造函数
6.4.3深拷贝构造函数 浅拷贝构造函数
浅拷贝:不复制数据,只复制指向数据的指针,因此多个指针指向同一份数据
深拷贝:会复制数据,每个指针指向独立的空间
#include <iostream>using namespace std;class demo
{
public:demo(int len = 0) //有默认参数的普通构造函数{size = len;arr = new int[size];for(int i = 0; i < size; i++){arr[i] = 0;}cout << "demo(int len = 0)----------\r\n";}demo(demo &obj)//拷贝构造函数{
#if 0//浅拷贝size = obj.size;arr = obj.arr;
#endif//深拷贝size = obj.size;arr = new int [size];for(int i =0 ; i < size ; i++){arr[i] = obj.arr[i];}cout << "demo(demo &obj)----------------\r\n";}void setint(int pos,int val){if(pos >= size || pos < 0){cout << "pos error!\r\n";}else{arr[pos] = val;}}void getint(int pos){if(pos >= size || pos < 0){cout << "pos error!\r\n";}else{cout << "arr[" << pos << "]" << arr[pos] << endl;}}
private:int *arr;int size;
};int main()
{
#if 0//浅拷贝demo obj(100);demo obj1(obj);obj.getint(1); //0obj1.getint(1); //0cout << "\r\n";obj.setint(1,200);obj.getint(1); //200obj1.getint(1); //200
#endif//深拷贝demo obj2(222);demo obj3(obj2);obj2.getint(1); //0obj3.getint(1); //0cout << "\r\n";obj2.setint(1,666);obj2.getint(1); //666obj3.getint(1); //0return 0;
}