C++
面向对象
后缀 .cpp
编译: g++ xxx.cpp
**封装:**封装的抽象过程,描述一类事物的特点 **类:**一类事物的统称 **对象:**某类事物的一个特别/个体
如何描述一类事物:数据成员,成员方法。
实例化对象:int i; 例: A a1; “实例化一个A类型的对象a1”
继承:核心,在原有的特点/功能上加上新特点/功能。 多态:延申, 同一条命令作用在不同对象上显示效果不同。
一、输入和输出
1.cin (输入) – 默认与键盘链接,接受从键盘输入的数据信息。 语法:cin >> 变量 ; 2.cout(输出) – 默认与屏幕链接,将数据显示到屏幕上。 语法: cout << 变量 ;
如果没指定名空间:using namespace std; 域解析运算符
#include <iostream>
using namespace std;
int main()
{
int i;
char str[32];
cout << "Hello World!" << endl;
cin >> i;
cout << "i = " << i << " &i = " << &i << endl; //C++能自动识别变量类型
cin >> str;
cout << "str = " << str << endl;
return 0;
}
注意:C++在创建变量时,必须给变量一个初始值,否则会报错
二、封装
1.1 封装定义-属性和行为
封装的意义:
- 将属性和行为作为一个整体,表现生活中的事物
- 将属性和行为加以权限控制
语法: class 类名{ 访问权限: 属性 / 行为 };
class Clock
{
public:
void ShowTime();
void SetTime(int h,int m,int s);
private:
int hour;
int minute;
int second;
};
1.2 访问权限
访问权限有三种:
公共权限 public ==类内可以访问 类外可以访问==
保护权限 protected ==类内可以访问 类外不可以访问==
私有权限 private ==类内可以访问 类外不可以访问==
示例:
#include <iostream>
me/xiaolei/teacher/example/c++/hello.cpp' '
using namespace std;
//内联函数inline 1类内实现 2用inline关键字类内声明,实现可以写在类外
//public protected private
class Clock
{
public:
void ShowTime();
void SetTime(int h,int m,int s);
private:
int hour;
int minute;
int second;
};
void Clock::ShowTime()
{ cout << hour << ":" << minute << ":" << second << endl; }
void Clock::SetTime(int h,int m,int s)
{ hour = h; minute = m; second = s; }
int main()
{
Clock c1;
c1.ShowTime();
return 0;
}
inline 内联函数 带参宏 ,建议性机制 宏占用的是编译时间,不占用运行时间
对一个类进行计算大小,只能计算数据类型的大小,函数不计入空间大小
三、类中的特殊函数
3.1 构造函数
对象的初始化和清理也是两个非常重要的安全问题 一个对象或者变量没有初始状态,对其使用后果是未知 同样的使用完一个对象或变量,没有及时清理,也会造成一定的安全问题
构造函数作用:初始化,在一个对象生成的时候被隐式调用
默认有一个系统生成的构造函数,若果我们自行实现了构造函数,系统默认的那个不再生成 长相:函数与类同名,不需要返回值,可传参(1或多),可无参
构造函数语法:类名(){}
- 构造函数,没有返回值也不写void
- 函数名称与类名相同
- 构造函数可以有参数,因此可以发生重载
- 程序在调用对象时候会自动调用构造,无须手动调用,而且只会调用一次
代码演示:
#include <iostream>
using namespace std;
/*类中的特殊函数*/
/*
构造函数:作用:初始化,在一个对象生成的时候被隐式调用
默认有一个系统生成的构造函数,若我们自行实现了构造函数,系统默认的那个不再生成
长相:函数名与类同名,不需要返回值,可传参(可1个或多个)可无参
构造函数可以同时存在多个
*/
class Clock
{
public:
Clock(); //构造函数可以存在多个
Clock(int h);
void ShowTime();
void SetTime(int h,int m,int s);
private:
int hour;
int minute;
int second;
};
Clock::Clock()
{
cout << "Clock()" << endl;
hour = minute = second = 0;
}
Clock::Clock(int h)
{
cout << "Clock(int)" << endl;
hour = h ; minute = second = 0;
}
void Clock::ShowTime()
{ cout << hour << ":" << minute << ":" << second << endl; }
void Clock::SetTime(int h,int m,int s)
{ hour = h; minute = m; second = s; }
int main()
{
Clock c0;
Clock c1(4);
Clock c2(14,15);
// c1.ShowTime();
return 0;
}
类外不能复制
#include <iostream>
using namespace std;
/*类中的特殊函数*/
/*
构造函数:作用:初始化,在一个对象生成的时候被隐式调用
默认有一个系统生成的构造函数,若我们自行实现了构造函数,系统默认的那个不再生成
长相:函数名与类同名,不需要返回值,可传参(可1个或多个)可无参
构造函数可以同时存在多个
*/
class Clock
{
public:
Clock(int h=0,int m=0,int s=0);
void ShowTime();
void SetTime(int h,int m,int s);
private:
int hour;
int minute;
int second;
};
Clock::Clock(int h,int m,int s)
{
cout << "Clock(3*int)" << endl;
hour = h ;
minute = m;
second = s;
}
void Clock::ShowTime()
{ cout << hour << ":" << minute << ":" << second << endl; }
void Clock::SetTime(int h,int m,int s)
{ hour = h; minute = m; second = s; }
int main()
{
Clock c0;
Clock c1(4);
Clock c2(14,15);
// c1.ShowTime();
return 0;
}
3.2 析构函数
析构函数作用:清理或销毁,在一个对象生命周期即将终止时被隐式调用
默认有一个系统生成的析构函数,若果我们自行实现了构造函数,系统默认的那个不再生成 长相:函数与类同名,前面加~,不需要返回值
析构函数语法: ~类名(){}
- 析构函数,没有返回值也不写void
- 函数名称与类名相同,在名称前加上符号 ~
- 析构函数不可以有参数,因此不可以发生重载
- 程序在对象销毁前会自动调用析构,无须手动调用,而且只会调用一次
给变量加个大括号相当于一个临时变量
代码演示:
#include <iostream>
using namespace std;
/*类中的特殊函数*/
/*
析构函数:作用:清理或销毁,在一个对象生命周期即将终止时被隐式调用
默认有一个系统生成的析构函数,若我们自行实现析构函数,系统默认的那个不再生成
长相:函数名与类同名,前面加~,不需要返回值,不可传参
*/
class Clock
{
public:
Clock(int h=0,int m=0,int s=0);
~Clock();
void ShowTime();
void SetTime(int h,int m,int s);
private:
int hour;
int minute;
int second;
};
Clock::Clock(int h,int m,int s)
{
cout << "Clock(3*int)" << endl;
hour = h ;
minute = m;
second = s;
}
Clock::~Clock()
{
cout << "~Clock() " << hour << endl;
}
void Clock::ShowTime()
{ cout << hour << ":" << minute << ":" << second << endl; }
void Clock::SetTime(int h,int m,int s)
{ hour = h; minute = m; second = s; }
int main()
{
Clock c0;
{
Clock c2(14,15);
}
Clock c1(4);
return 0;
}
3.3 拷贝构造函数
拷贝构造函数作用:初始化,在一个对象生成的时候,且用相同类型的已存在的对象初始化时调用拷贝构造
默认有一个系统生成的拷贝构造函数,若果我们自行实现了拷贝构造函数,系统默认的那个不再生成 长相:函数与类同名,不需要返回值,可传参(参数为常量的引用)。
代码演示:常量的引用
”同一块存储的空间有相同的名字“
#include <iostream>
using namespace std;
/*类中的特殊函数*/
/*
拷贝构造函数:作用:初始化 ,在一个对象生成时,且用相同类型的已存在的对象初始化时调用拷贝构造
默认有一个系统生成的拷贝构造函数,若我们自行实现了拷贝构造函数,系统默认的那个不再生成
长相:函数名与类同名,无返回值,参数为常引用
*/
class Clock
{
public:
Clock(int h=0,int m=0,int s=0);
Clock(const Clock &other);
~Clock();
void ShowTime();
void SetTime(int h,int m,int s);
private:
int hour;
int minute;
int second;
};
Clock::Clock(int h,int m,int s)
{
cout << "Clock(3*int)" << endl;
hour = h ;
minute = m;
second = s;
}
Clock::Clock(const Clock &other)
{
cout << "Clock(&)" << endl;
hour = other.hour;
minute = other.minute;
second = other.second;
}
Clock::~Clock()
{
cout << "~Clock() " << hour << endl;
}
void Clock::ShowTime()
{ cout << hour << ":" << minute << ":" << second << endl; }
void Clock::SetTime(int h,int m,int s)
{ hour = h; minute = m; second = s; }
int main()
{
Clock c1(4);
Clock c2 = c1;
c2.ShowTime();
return 0;
}
四、C++内存模型
C++程序在执行时,将内存大方向划分为4个区域
- 代码区:存放函数体的二进制代码,由操作系统进行管理的
- 全局区:存放全局变量和静态变量以及常量
- 栈区:由编译器自动分配释放, 存放函数的参数值,局部变量等
- 堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收
new && delete
? C++中利用new操作符在堆区开辟数据
? 堆区开辟的数据,由程序员手动开辟,手动释放,释放利用操作符 delete
? 语法:new 数据类型
? 利用new创建的数据,会返回该数据对应的类型的指针
示例1: 基本语法
#include <iostream>
using namespace std;
int main()
{
char *p = new char;
if(p == NULL)
return -1;
*p = 'a';
cout << *p << endl;
delete p; //利用delete释放堆区数据
return 0;
}
示例2:开辟数组
#include <iostream>
using namespace std;
/* new delete */
class Clock
{
public:
Clock(int h=0,int m=0,int s=0);
Clock(const Clock &other);
~Clock();
void ShowTime();
void SetTime(int h,int m,int s);
private:
int hour;
int minute;
int second;
};
Clock::Clock(int h,int m,int s)
{
cout << "Clock(3*int)" << endl;
hour = h ;
minute = m;
second = s;
}
Clock::Clock(const Clock &other)
{
cout << "Clock(&)" << endl;
hour = other.hour;
minute = other.minute;
second = other.second;
}
Clock::~Clock()
{
cout << "~Clock() " << hour << endl;
}
void Clock::ShowTime()
{ cout << hour << ":" << minute << ":" << second << endl; }
void Clock::SetTime(int h,int m,int s)
{ hour = h; minute = m; second = s; }
//堆区开辟数组
int main()
{
//执行new时,一定会经历构造的过程
Clock *p = new Clock[5]; //连续的需要五个这个类型的空间
delete []p;
return 0;
}
示例3:
#include <iostream>
using namespace std;
class A
{
public:
A() { str = new char[1]; *str = '\0' };
~A() { delete []str; }
void Show() { cout << str << endl; }
private:
char *str;
};
int main()
{
A a1;
return 0;
}
五、继承
继承是面向对象三大特性之一
有些类与类之间存在特殊的关系,例如下图中:
我们发现,定义这些类时,下级别的成员除了拥有上一级的共性,还有自己的特性。 这个时候我们就可以考虑利用继承的技术,减少重复代码
5.1 继承方式:
继承方式一共有三种:
父类-子类 基类-派生类
parent->: public protected private
public: public protected -
protected: protected protected -
private: private private -
示例:
#include <iostream>
using namespace std;
class A
{
public:
A() {cout << "A()" << endl;}
~A() {cout << "~A()" << endl;}
void GetA() { cout << "A::GetA() " << a << endl;}
protected:
void Show() { cout << "A::Show()" << a << endl;}
private:
int a;
};
class B : public A
{
public:
B() {cout << "B()" << endl;}
~B() {cout << "~B()" << endl;}
void GetShow() { Show(); }
void GetA() { cout << "B::GetA() " << endl;}
};
int main()
{
B tmp;
tmp.GetA();
return 0;
}
|