引入
下面是一个从菜鸟抄来的例子,可以看到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,类型为 BoxBox Box2; // 声明 Box2,类型为 BoxBox Box3; // 声明 Box3,类型为 Boxdouble 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;
}