类中说明的重载
#include<bits/stdc++.h>
using namespace std;
/**
* 在类中说明的重载
* */
class Cube {
public:
Cube() {
height = 1;
width = 2;
length = 3;
}
Cube(int h, int w, int l) {
height = h;
width = w;
length = l;
}
private:
int height;
int width;
int length;
};
int main() {
Cube c1;
Cube c1(4, 5, 6);
return 0;
}
基类成员在派生类的重载
#include<bits/stdc++.h>
using namespace std;
/**
* 基类成员在派生类的重载
* */
class Point {
public:
Point(int x, int y) {
Point::x = x;
Point::y = y;
}
float area() {
return 0.0;
}
private:
int x;
int y;
};
class Circle: public Point {
public:
Circle(int x, int y, int r): Point(x, y) {
Circle::radius = r;
}
float area() {
return 3.1415926535*radius*radius;
}
private:
int radius;
};
int main() {
Point p(10, 10);
Circle c(5, 5, 20);
cout<<"point1:"<<p.area()<<endl;
cout<<"circle1:"<<c.area()<<endl;
cout<<"point1:"<<c.Point::area()<<endl; // 可以通过作用域符号找到基类的同名函数
return 0;
}
虚函数
#include<bits/stdc++.h>
using namespace std;
/**
* 虚函数的作用
* */
class Undergra {
public:
virtual void cal_fee() {
fee1 = 4200;
fee2 = 800;
fee3 = 400;
fee = fee1 + fee2 + fee3;
}
virtual void dis() {
cout<<"undergraduate fee:"<<endl;
cout<<"study fee:"<<fee1<<endl;
cout<<"sleep fee:"<<fee2<<endl;
cout<<"other fee:"<<fee3<<endl;
cout<<"total fee:"<<fee<<endl;
}
protected:
int fee1;
int fee2;
int fee3;
int fee;
};
class PostGra: public Undergra {
public:
void cal_fee() {
fee1 = 1800;
fee2 = 400;
fee = fee1 + fee2;
}
void dis() {
cout<<"postgraduate fee:"<<endl;
cout<<"sleep fee:"<<fee1<<endl;
cout<<"other fee:"<<fee2<<endl;
cout<<"total fee:"<<fee<<endl;
}
};
int main() {
Undergra u1;
PostGra p1;
Undergra *ptr = &u1;
ptr->cal_fee();
ptr->dis();
ptr = &p1;
ptr->cal_fee();
ptr->dis();
return 0;
}
虚函数是其他类的派生类,不会影响基类的同名函数
#include<bits/stdc++.h>
using namespace std;
/**
* 虚函数
* 如果基类成员函数是虚函数,那么所有派生类都是虚函数
* 如果虚函数是其他类的派生类,那么基类的同名函数保持原有性质
* */
class A {
public:
void f(int i) {
cout<<"A"<<endl;
}
};
class B: public A {
public:
virtual void f(int i) {
cout<<"B"<<endl;
}
};
class C: public B {
public:
void f(int i) {
cout<<"C"<<endl;
}
};
class D: public C {
public:
void f(int ) {
cout<<"D"<<endl;
}
};
int main() {
A *pa, a;
B *pb, b;
C c;
D d;
pa = &a; pa->f(1);
pa = &b; pa->f(1);
pa = &c; pa->f(1);
pa = &d; pa->f(1);
// 由于 A 的 f 不是虚函数,那么其子类都会调用 A 的f函数
// B 的f是虚函数,那么其子类的f 都具有虚函数的性质
pb = &b; pb->f(1);
pb = &c; pb->f(1);
pb = &d; pb->f(1);
return 0;
}
只有通过基类指针和引用才能实现虚函数特性
#include<bits/stdc++.h>
using namespace std;
/**
* 只有通过基类指针和引用才能实现虚函数特性
* */
class B {
public:
virtual void f() {
cout<<"B f"<<endl;
}
};
class D: public B {
public:
void f() {
cout<<"D f"<<endl;
}
};
int main() {
D d;
B *pb = &d, &rb = d, b;
b = d; // 截断赋值,因此实质还是调用B的函数
b.f();
pb->f(); // 虚函数特性
rb.f(); // 虚函数特性
return 0;
}
派生类从基类继承的成员函数访问虚函数时,会访问派生类的版本
#include<bits/stdc++.h>
using namespace std;
/**
* 派生类从基类继承的成员函数访问虚函数时,会访问派生类的版本
* */
class B {
public:
void f() {
g();
}
virtual void g() {
cout<<"B g"<<endl;
}
};
class D: public B {
public :
void g() {
cout<<"D g"<<endl;
}
};
int main() {
D d;
d.f(); // 这里访问的是派生类中的g,如果 virtual 关键字去掉,那么访问基类中的g
return 0;
}
虚函数调用过程
#include<bits/stdc++.h>
using namespace std;
/**
* 虚函数调用过程
* */
class B {
public:
void f() {
cout<<"B f"<<endl;
}
virtual void vf() {
cout<<"B vf"<<endl;
}
void ff() {
vf();
f();
}
virtual void vff() {
vf();
f();
}
};
class D: public B {
public:
void f() {
cout<<"D f"<<endl;
}
void ff() {
f();
vf();
}
void vf() {
cout<<"D vf"<<endl;
}
};
int main() {
D d;
B *pb = &d;
pb->f(); // 非虚函数,调用 B 的f
pb->ff(); // 非虚函数,调用 B 的ff,从而调用 D的vf 以及B 的f
pb->vf(); // 虚函数,调用 D 的vf
pb->vff(); // 虚函数,调用 D 的vf 以及 B 的f
return 0;
}
虚析构函数
#include<bits/stdc++.h>
using namespace std;
/**
* 虚析构函数
* */
class A {
public :
virtual ~A() {
cout<<"destruct A"<<endl;
}
};
class B: public A {
public:
~B() {
cout<<"destruct B"<<endl;
}
};
int main() {
A *p = new B();
delete p;
return 0;
}
输出
destruct B
destruct A
如果没有 virtual ,那么只会调用 A 的析构函数
纯虚函数
#include<bits/stdc++.h>
using namespace std;
/**
* 纯虚函数
* */
class Point {
public:
Point(int i = 0, int j = 0) {
x0 = i;
y0 = j;
}
virtual void Draw() = 0;
private:
int x0, y0;
};
class Line: public Point {
public:
Line(int i = 0, int j = 0, int m = 0, int n = 0): Point(i, j) {
x1 = m;
y1 = n;
}
void Draw() {
cout<<"draw line"<<endl;
}
private:
int x1, y1;
};
class Ellipse: public Point {
public:
Ellipse(int i = 0, int j = 0, int p = 0, int q = 0): Point(i, j) {
x2 = p;
y2 = q;
}
void Draw() {
cout<<"draw ellipse"<<endl;
}
private:
int x2, y2;
};
int main() {
Line *line = new Line;
Ellipse *ellipse = new Ellipse;
line->Draw();
ellipse->Draw();
delete line, ellipse;
return 0;
}
抽象类
#include<bits/stdc++.h>
using namespace std;
/**
* 抽象类
* */
class Figure {
public:
virtual float area()=0;
};
class Circle: public Figure {
public:
Circle(float r) {
radius = r;
}
float area() {
return radius * radius * 3.1415926535;
}
private:
float radius;
};
class Triangle: public Figure {
public:
Triangle(float h, float w) {
high = h;
width = w;
}
float area() {
return high * width * 0.5;
}
protected:
float high, width;
};
class Rectangle: public Triangle {
public:
Rectangle(float h, float w):Triangle(h, w) {
}
float area() {
return high * width;
}
};
int main() {
Figure *p[6];
p[0] = new Triangle(3.0, 2.0);
p[1] = new Rectangle(2.5, 3.0);
p[2] = new Rectangle(5.0, 1.0);
p[3] = new Rectangle(3.0, 6.0);
p[4] = new Circle(5.2);
p[5] = new Circle(8.0);
for(int i = 0; i < 6; i++) {
printf("area[%d] = %f\n", i, p[i]->area());
}
return 0;
}
抽象类不能建立对象
#include<bits/stdc++.h>
using namespace std;
/**
* 抽象类不能建立对象
* 函数原型不一样,仍然是抽象类
* */
class Figure {
protected:
double x, y;
public:
void set(double i, double j) {
x = i;
y = j;
}
virtual void area() = 0;
};
class Triangle : public Figure {
public:
void area() {
printf("triangle area : %f\n", x*y*0.5);
}
};
class Rectangle : public Figure {
public:
void area(int i) { // 只有函数原型一模一样才是虚函数,否则是重载,因此 Rectangle 仍然是抽象类
printf("rectangle area : %f\n", x*y);
}
};
int main() {
Figure *pf;
// Figure f; // 错误,抽象类不能建立对象
// Rectangle r; // 错误,area 是重载而不是虚函数,因此仍然是抽象类
Triangle t;
t.set(10, 20);
pf = &t;
pf->area();
Figure &rf = t;
rf.set(20, 20);
rf.area();
return 0;
}