C++基础
1-对象
(1)存储,同一类不同对象,属性值不同,但行为相同,所有函数代码存放在公共区
2-类,C++基本单位
(1)成员变量,除了静态的,不初始化,构造对象时,通过构造函数初始化,或者对象索引初始化等
3-封装,类给我们提供的仅仅是函数接口,好的编程方式,类成员变量是隐藏的。
4-抽象
5-继承,单重继承,多重继承(一子类,多个父类),重复继承(一子类,多个父类,父类们,都继承同一个子类),变量名的处理问题,加类名标识
6-多态
静态多态(重载)模版等,编译时确定
动态多态(虚函数,纯虚函数),运行时确定调用哪个函数
基类对象指针,能指向自己类型,以及子类类型的指针,而子类指针不能反过来指向基类指针
基类对象,可以由子类,自己类型对象赋值,反过来不可以。
一个基类,被多个子类继承,基类有两个函数,一个虚函数,一个普通函数。都被子类重写。现在用基类指针,指向子类对象,调用函数,虚函数因指向子类不同而不同,而不是虚函数,一直调用基类自己的函数实现。(基类必须为指针,用对象不行)
#include <iostream>
using namespace std;
class A
{
public:
virtual fun() // 虚函数也可以实现函数体,有虚函数的类
{ // 不一定是抽象类,纯虚函数不能有实现,有纯虚函数的类一定是抽象类
cout << "A" << endl;
}
};
class B:public A
{
public:
fun()
{
cout << "B" << endl;
}
};
class C:public A
{
public:
fun()
{
cout << "C" << endl;
}
};
int main()
{
/* 对象,没有多态
A a;
B b = B();
C c = C();
a = b;
a.fun();
a = c;
a.fun()
*/
A *a;
B b = B();
C c = C();
a = &b;
a->fun();
a = &c;
a->fun();
return 0;
}
using namespace std;
class A
{
public:
virtual fun() // 虚函数也可以实现函数体,有虚函数的类
{ // 不一定是抽象类,纯虚函数不能有实现,有纯虚函数的类一定是抽象类
cout << "A" << endl;
}
};
class B:public A
{
public:
fun()
{
cout << "B" << endl;
}
};
class C:public A
{
public:
fun()
{
cout << "C" << endl;
}
};
int main()
{
/* 对象,没有多态
A a;
B b = B();
C c = C();
a = b;
a.fun();
a = c;
a.fun()
*/
A *a;
B b = B();
C c = C();
a = &b;
a->fun();
a = &c;
a->fun();
return 0;
}
纯虚函数:其实就是普通虚函数的,限制版,让你不得不多态,基类只能是指针,不能实例化为对象,子类必须实现虚函数,也就多态了。
virtual int fun() = 0;, 类也变成抽象类,(有纯虚函数的类才是抽象类)只能声明指针,不能实例化对象。
基础抽象类的子类都该实现纯虚函数的定义,不然子类也是抽象类。
7-构造函数
(1)同类名,public,没有返回值,没有定义,系统用空函数,在创建对象时,隐式调用
(2)可内联,重载,带默认形参
(3)
#include <iostream>
using namespace std;
class POINT
{
public:
POINT(int xx = 0, int yy = 0);
~POINT();
private:
int x;
int y;
};
// 定义,xx传值给x,相当于this.x = xx;
POINT::POINT(int xx, int yy):x(xx), y(yy)
{
}
POINT::~POINT()
{
cout << "析构函数" << endl;
}
int main()
{
POINT point = POINT(1,3); // 有别于java,对象,程序结束调用析构函数
POINT *p = new POINT(1,3); // 指针,需要delete p,才会调用析构函数
return 0;
}
using namespace std;
class POINT
{
public:
POINT(int xx = 0, int yy = 0);
~POINT();
private:
int x;
int y;
};
// 定义,xx传值给x,相当于this.x = xx;
POINT::POINT(int xx, int yy):x(xx), y(yy)
{
}
POINT::~POINT()
{
cout << "析构函数" << endl;
}
int main()
{
POINT point = POINT(1,3); // 有别于java,对象,程序结束调用析构函数
POINT *p = new POINT(1,3); // 指针,需要delete p,才会调用析构函数
return 0;
}
(4)拷贝构造函数, 形参为本类的对象引用 POINT (POINT &point);
使用场合, CPOINT B = A; 函数形参为类对象 fun(A), 函数返回值为类对象return A
(5)派生类构造函数,显式调用基类构造函数,初始化基类成员,
B::B(int x1, char c1, int t1, double z1, int w1):A(x1, c1, t1),第二个基类() // 这样相当于在函数内,直接调用,也就是传值给基类的
{
// 派生类成员,
this.z = z1;
this.w = w1;
}
{
// 派生类成员,
this.z = z1;
this.w = w1;
}
(5) 调用顺序,基类到子类
8-析构函数
(1)public, ~开始,无参数,无返回值
(2)一般用于delete成员变量,或者清空等name[0] = '\0'之类
(3)允许内联,没有声明会系统默认
(4)声明虚函数,delete p,基类指针才能析构实际指向的子类,而子类析构函数,会出发回调知道最后基类析构函数。
(1)public
9-访问权限
用于成员:public(对象访问), protected(派生类函数访问),private默认(类本身函数访问)
用于类的继承方式:
public 基类属性照搬,基类private不能被访问
protected public变protect,其他照搬,基类private不能被访问
private public,protected变private, 基类private不能被访问
10-模板
函数模版:1-调用规则,先寻找非模版,若能找到符合,不使用模版,2-没有找模版,3-模版没有找能通过类型转换匹配的,没有报错
template <class T>
void swap(T &x1, T &x2)
{
T x;
x = x1, x1 = x2, x2 = x;
}
void swap(T &x1, T &x2)
{
T x;
x = x1, x1 = x2, x2 = x;
}
调用和其他函数一样
类模板
#include <iostream> // class可用typename代替
using namespace std;
template <class T1, class T2>
class CSore
{
public:
CSore(T1 xx, T2 yy);
T2 get();
void set(T2 yy);
private:
T1 x;
T2 y;
};
template <class T1, class T2> // 得重复
T2 CSore<T1, T2>::get()
{
return y;
}
template <class T1, class T2> // 得重复
void CSore<T1, T2>::set(T2 yy)
{
y = yy;
}
template <class T1, class T2> // 得重复
CSore<T1, T2>::CSore(T1 xx, T2 yy)
{
x = xx;
y = yy;
}
int main()
{
CSore<int, char>csore(56, 'u'); // 创建模版累对象,特殊点,接下来函数的调用,同函数模版
csore.set('r');
cout << csore.get() << endl;
return 0;
}
using namespace std;
template <class T1, class T2>
class CSore
{
public:
CSore(T1 xx, T2 yy);
T2 get();
void set(T2 yy);
private:
T1 x;
T2 y;
};
template <class T1, class T2> // 得重复
T2 CSore<T1, T2>::get()
{
return y;
}
template <class T1, class T2> // 得重复
void CSore<T1, T2>::set(T2 yy)
{
y = yy;
}
template <class T1, class T2> // 得重复
CSore<T1, T2>::CSore(T1 xx, T2 yy)
{
x = xx;
y = yy;
}
int main()
{
CSore<int, char>csore(56, 'u'); // 创建模版累对象,特殊点,接下来函数的调用,同函数模版
csore.set('r');
cout << csore.get() << endl;
return 0;
}
11-命名空间:解决命名冲突问题,可以定义无名命名空间
#include <iostream>
using namespace std;
namespace one
{
void fun()
{
cout << "funOne" << endl;
}
}
namespace two
{
void fun()
{
cout << "funTwo" << endl;
}
}
int main()
{
one::fun();
two::fun();
return 0;
}
using namespace std;
namespace one
{
void fun()
{
cout << "funOne" << endl;
}
}
namespace two
{
void fun()
{
cout << "funTwo" << endl;
}
}
int main()
{
one::fun();
two::fun();
return 0;
}
12-异常处理
#include <iostream>
using namespace std;
int divid(int x, int y)
{
if (0 == y)
throw y;
return x/y;
}
int main()
{
try
{
cout << "18/3 = " << divid(18,3) << endl;
cout << "18/0 = " << divid(18,0) << endl;
}
catch(int y) // (...)可用省略号处理
{
cout << "y不能为:" << y << endl;
}
return 0;
}
using namespace std;
int divid(int x, int y)
{
if (0 == y)
throw y;
return x/y;
}
int main()
{
try
{
cout << "18/3 = " << divid(18,3) << endl;
cout << "18/0 = " << divid(18,0) << endl;
}
catch(int y) // (...)可用省略号处理
{
cout << "y不能为:" << y << endl;
}
return 0;
}
13-运算符重载
类中
friend ostream &operator<<(ostream &stream, const Employee &employee);
定义
ostream &operator<<(ostream &stream, const &Employee);
{
cout << employee.name << employee.grassPay << endl;
return stream;
}
friend ostream& operator<<(ostream &stream, const Employee &employee);
ostream& operator<<(ostream &stream, const Employee &employee)
{
cout << employee.name << "$" << setiosflags(ios::fixed) << setprecision(2) << employee.grossPay << endl;
return stream;
}
//不可去掉两个&。
bool Employee::operator>(const Employee& otherEmployee)const
{
return grossPay > otherEmployee.grossPay;
}
friend ostream &operator<<(ostream &stream, const Employee &employee);
定义
ostream &operator<<(ostream &stream, const &Employee);
{
cout << employee.name << employee.grassPay << endl;
return stream;
}
friend ostream& operator<<(ostream &stream, const Employee &employee);
ostream& operator<<(ostream &stream, const Employee &employee)
{
cout << employee.name << "$" << setiosflags(ios::fixed) << setprecision(2) << employee.grossPay << endl;
return stream;
}
//不可去掉两个&。
bool Employee::operator>(const Employee& otherEmployee)const
{
return grossPay > otherEmployee.grossPay;
}
. * :: sizeof ?::不可重载
返回值类型 operator 运算符 (形参)
{
函数体
}
1-为类函数
2-重载为类的友元函数
#include <iostream>
using namespace std;
class CComplex
{
private:
double real;
double image;
public:
CComplex(double r = 0.0, double i = 0.0)
{
real = r;
image = i;
}
~CComplex(){};
CComplex operator + (const CComplex &cc)
{
CComplex temp;
temp.real = real + cc.real; // 注意了,在类里面,real等虽然为private却可以使用。
temp.image = image + cc.image; // 类里面,声明的对象,不用遵守private等权限
return temp;
}
void fun(const CComplex &cc)
{
cout << cc.real << endl;
}
};
int main()
{
CComplex c1(3.4, 6.7), c2(5.9, 9.8);
CComplex c = c1 + c2;
c.fun(c);
return 0;
}
using namespace std;
class CComplex
{
private:
double real;
double image;
public:
CComplex(double r = 0.0, double i = 0.0)
{
real = r;
image = i;
}
~CComplex(){};
CComplex operator + (const CComplex &cc)
{
CComplex temp;
temp.real = real + cc.real; // 注意了,在类里面,real等虽然为private却可以使用。
temp.image = image + cc.image; // 类里面,声明的对象,不用遵守private等权限
return temp;
}
void fun(const CComplex &cc)
{
cout << cc.real << endl;
}
};
int main()
{
CComplex c1(3.4, 6.7), c2(5.9, 9.8);
CComplex c = c1 + c2;
c.fun(c);
return 0;
}