继承
当创建一个类时,不需要重新编写新的数据成员和成员函数,只需指定新建的类继承了一个已有的类的成员。这个已有的类称为基类,新建的类称为派生类。
派生类不可访问基类的private成员。
- 一个类可以派生自多个类。
- 派生类可以访问基类中所有的非私有成员。
- 一个派生类继承了所有的基类方法,除了基类的构造函数、析构函数和拷贝构造函数。重载运算符和友元函数。
- 派生类在继承基类的成员变量时,会单独开辟一块内存保存基类的成员变量,因此派生类自己的成员变量即使和基类的成员变量重名,但是也不会引起冲突。
class derived-class: access-specifier base-class
access-specifier 是 public、protected 或 private 其中的一个,base-class 是之前定义过的某个类的名称。如果未使用访问修饰符 access-specifier,则默认为 private。
继承类性决定了基类的成员在派生类是什么类型。举个例子——当一个类派生自保护基类时,基类的公有和保护成员将成为派生类的保护成员。
代码举例:
#include <iostream>
using namespace std;
class Goust
{
public:
void one(int c)
{
a = c;
}
void two(int d)
{
b = d;
}
protected:
int a;
int b;
};
class Bgoust: public Goust
{
public:
int three()
{
return (a * b);
}
};
int main(void)
{
Bgoust P;
P.one(5);
P.two(7);
cout << P.three() << endl;
return 0;
}
输出
多继承
class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,…
{
...............
};
我们不能够在子类的成员函数体中调用基类的构造函数来为成员变量进行初始化,但是可以把基类的构造函数放在子类构造函数的初始化列表上,以此实现调用基类的构造函数来为子类从基类继承的成员变量初始化。
举例:
#include <iostream>
using namespace std;
class Goust
{
public:
Goust(int c,int d)
{
a = c;
b = d;
}
protected:
int a;
int b;
};
class Bgoust: public Goust
{
public:
Bgoust(int a,int b):Goust(a,b)
{ }
int three()
{
return a*b;
}
};
int main(void)
{
Bgoust Bgoust(4,5);
cout << Bgoust.three() << endl;
return 0;
}
输出
重载
重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不相同。
调用一个重载函数或重载运算符时,编译器通过把您所使用的参数类型与定义中的参数类型进行比较,决定选用最合适的定义。选择最合适的重载函数或重载运算符的过程,称为重载决策。
函数重载
在同一个作用域内,可以声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同。
#include <iostream>
using namespace std;
class Goust
{
public:
void a()
{
cout<<"happy"<<endl;
}
void a(int i)
{
cout<<i<<endl;
}
void a(char b[])
{
cout<<b<<endl;
}
};
int main(void)
{
char b[]="forever";
Goust g;
g.a();
g.a(666);
g.a(b);
return 0;
}
输出
运算符重载
重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。
#include <iostream>
using namespace std;
class Goust
{
private:
double i;
double j;
public:
Goust(int a=0, int b=0)//给参数一个值,使在调用时,无论是否给参数均可
{
i = a;
j = b;
}
void put()
{
cout << i << '+' << j << endl;
}
Goust operator ++()//前缀自增
{
i++;
j++;
return *this;
}
Goust operator ++(int)//后缀自增,参数需要加int
{
Goust g=*this;
++*this;
return g;
}
};
int main()
{
Goust h(5,6),p,y;
h.put();
p=++h;
h.put();
p.put();
y=h++;
h.put();
y.put();
return 0;
}
输出
可重载运算符
双目算术运算符 | + (加),-(减),*(乘),/(除),% (取模) |
关系运算符 | ==(等于),!= (不等于),< (小于),> (大于),<=(小于等于),>=(大于等于) |
逻辑运算符 | ||(逻辑或),&&(逻辑与),!(逻辑非) |
单目运算符 | + (正),-(负),*(指针),&(取地址) |
自增自减运算符 | ++(自增),--(自减) |
位运算符 | | (按位或),& (按位与),~(按位取反),^(按位异或),,<< (左移),>>(右移) |
赋值运算符 | =, +=, -=, *=, /= , % = , &=, |=, ^=, <<=, >>= |
空间申请与释放 | new, delete, new[ ] , delete[] |
其他运算符 | ()(函数调用),->(成员访问),,(逗号),[](下标) |
太多了不好记,主要记不可重载
不可重载
. | 成员访问运算符 |
.*/->* | 成员指针访问运算符 |
:: | 域运算符 |
sizeof | 长度运算符 |
?: | 条件运算符 |
# | 预处理符号 |
运算重载符四不可:
不可改变语法结构、操作数的个数、优先级、结合性。