引入
下面是一个从菜鸟抄来的例子,可以看到BOX定义了两个公共函数,get和set,在类里面声明,在外面定义,也可以直接在里面定义。
#include <iostream>
using namespace std;
class Box
{
public:
double length; // 长度
double breadth; // 宽度
double height; // 高度
// 成员函数声明
double get(void);
void set( double len, double bre, double hei );
};
// 成员函数定义
double Box::get(void)
{
return length * breadth * height;
}
void Box::set( double len, double bre, double hei)
{
length = len;
breadth = bre;
height = hei;
}
int main( )
{
Box Box1; // 声明 Box1,类型为 Box
Box Box2; // 声明 Box2,类型为 Box
Box Box3; // 声明 Box3,类型为 Box
double volume = 0.0; // 用于存储体积
// box 1 详述
Box1.height = 5.0;
Box1.length = 6.0;
Box1.breadth = 7.0;
// box 2 详述
Box2.height = 10.0;
Box2.length = 12.0;
Box2.breadth = 13.0;
// box 1 的体积
volume = Box1.height * Box1.length * Box1.breadth;
cout << "Box1 的体积:" << volume <<endl;
// box 2 的体积
volume = Box2.height * Box2.length * Box2.breadth;
cout << "Box2 的体积:" << volume <<endl;
// box 3 详述
Box3.set(16.0, 8.0, 12.0);
volume = Box3.get();
cout << "Box3 的体积:" << volume <<endl;
return 0;
}
继承
成员类型
与其它语言类似,都有protected、private以及public
private 成员只能被本类成员(类内)和友元访问,不能被派生类访问;
protected 成员可以被派生类访问。
class b{
protected:
int bvalue = 5;
};
class a::b{
public:
void fun(){
cout<<bvalue<<endl;//能访问父类的protected, 不能是private
}
};
protected能被继承的类在成员函数中访问,但不能被实例化的变量调用。
无论是声明还是继承,默认就是private
class a{
int x;//默认private
};
父子变量名冲突
假如子类中变量与父类变量名冲突了。
class B{
public:
int age = 100;
};
class A::public B{
public:
int age = 10;
};
int main(void){
A a;
cout<<a.age;//10。
cout<<a.B::age;//命名空间来获取父类 100
}
继承类型
- 公有继承(public):当一个类派生自公有基类时,基类的公有成员也是派生类的公有成员,基类的保护成员也是派生类的保护成员,基类的私有成员不能直接被派生类访问,但是可以通过调用基类的公有和保护成员来访问。
- 保护继承(protected): 当一个类派生自保护基类时,基类的公有和保护成员将成为派生类的保护成员。
- 私有继承(private):当一个类派生自私有基类时,基类的公有和保护成员将成为派生类的私有成员。
构造和析构
构造和析构都是没有返回值的,可以允许重载。
初始化列表:用于在构造函数中快速初始化成员变量。
下面代码就直接将构造函数传过来的a赋值给X,b给Y,c给Z
C::C( double a, double b, double c): X(a), Y(b), Z(c)
{
....
}
拷贝构造函数:能直接拷贝一个对象构造一个新的对象
是构造函数的一种,属于构造函数的重载。
C::C(const ClassName& other);
C c1;
C c2 = C(c1);//能将c1的所有值复制给c2,且c2和c1后续没有什么引用关系。
能用于函数传形参,形参为对象的时候
析构函数:它会在每次删除所创建的实例对象时执行,用于最后释放资源。
与构造函数类似,就是在前面多了个波浪~
C{
public:
C()
~C();
};
友元变量
友元变量和友元类都不是成员函数和变量,但是可以访问其中的private和protected,只需要在类定义中多一个定义友元的firend关键字。
class Box
{
double width;
public:
friend void printWidth(Box box);
friend class BigBox;
void setWidth(double wid);
};
class BigBox
{
public :
void Print(int width, Box &box)
{
// BigBox是Box的友元类,它可以直接访问Box类的任何成员
box.setWidth(width);
cout << "Width of box : " << box.width << endl;
}
};
// 成员函数定义
void Box::setWidth(double wid)
{
width = wid;
}
// 请注意:printWidth() 不是任何类的成员函数
void printWidth(Box box)
{
/* 因为 printWidth() 是 Box 的友元,它可以直接访问该类的任何成员 */
cout << "Width of box : " << box.width << endl;
}
静态成员函数
静态成员函数和静态成员变量都只是在普通的变量上加一个static,效果是可以直接通过类名访问,不属于实例化对象的东西,属于类。
class MyClass {
public:
static void staticFunction() {
}
};
同时,假如是内部的函数,可以直接调用,不用加类名。
派生类的函数也可以直接调用,不用加命名空间。
多态
多态就类似java的抽象类, 基类用virtual关键字定义一个纯虚函数,而子类就必须用override关键字重写纯虚函数。
class Shape {
public:
virtual void draw() {
std::cout << "绘制形状" << std::endl;
}
};
class Rectangle : public Shape {
public:
void draw() override {
std::cout << "绘制矩形" << std::endl;
}
};
class Circle : public Shape {
public:
void draw() override {
std::cout << "绘制圆形" << std::endl;
}
};
int main() {
Shape* shape1 = new Rectangle();
Shape* shape2 = new Circle();
shape1->draw(); // 调用Rectangle的draw函数
shape2->draw(); // 调用Circle的draw函数
delete shape1;
delete shape2;
return 0;
}