类&对象
一个普普通通的类:
class Box{ private: double length; double width; public: int size;
double getV(){ return length*width; }
void setLength(double _length); void setWidth(double _width); };
void Box::setLength(double _length){ length = _length; }
void Box::setWidth(double _width){ width = _width; }
|
调用:
Box box; box.setLength(100); box.setWidth(20);
|
修饰符
常见的有私有(private)和public(公共)修饰符,还有一个保护(protected)成员:
在Box类中加入一个保护成员:
派生类:
class SmallBox:Box {
public: void setSmallAge(int _age); int getSmallAge();
};
void SmallBox::setSmallAge(int _age){ age = _age; }
int SmallBox::getSmallAge(){ return age; }
|
类构造函数
构造函数用于创建该对象,并赋予初始值。
Box类的构造函数也可以理解成返回Box类型的成员方法,同样需要在类中定义,在内部或者外部实现。
public: int size; Box(); Box(double _length,int _size);
|
实现:
Box::Box(){
}
Box::Box(double _length,int _size){ length = _length; size = _size; }
Box::Box(double _length,int _age){ length = _length; age = _age; }
|
使用:
Box box1(12,12); cout << "box1:" << box1.size << endl;
|
析构函数
类的析构函数是类的一种特殊的成员函数,它会在每次删除所创建的对象时执行。
析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,也不能带有任何参数。析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。
public: ~Box();
Box::~Box(){ cout << "box deleted" <<endl; }
|
我们在对象删除的时候打印,查看是否执行了析构函数。
友元函数
友元函数使用friend
修饰符修饰,不仅仅是函数,对类同样有效,成为友元类。
我们在类外部定义一个普通函数:
void printSth(Box box){ // 在Box类中设置了友元函数,所以能访问Box的所有成员 cout << "friend:" << box.length << endl; }
|
在Box类中加入并使用friend修饰:
class Box{
private: double length; double width; public: friend void printSth(Box box);
protected: int age; };
|
友元函数能够访问该类的私有成员和保护成员。
参考:https://www.cnblogs.com/balingybj/p/4778247.html
内联函数
和kotlin中内联函数相似
inline int Max(int i,int j){ return i >= j ? i : j; }
|
this指针
指向本类或者该函数的地址,用来调用自身成员。
void prin(){ cout << this->length <<endl; }
|
友元函数没有this指针,因为其不是类的成员,只有成员函数才有this指针。
类指针
指向类成员的指针,使用->
来使用其类成员
Box box;
Box *ptrBOX; ptrBOX = &box;
cout << ptrBOX->size <<endl;
|
static静态
静态成员
- 对于类的静态成员来说,无论有多少个对象,只存在一个静态成员副本。
- 静态成员在所有类对象中是共享的。
- 每次创建新的类对象,需要注意静态成员值的变化。
private: static int money;
|
在类外部进行初始化:
以下展示了静态成员在创建多个类对象时候的变化:
class Box { private: static int money; static int initCount; public: void setMoney(int _money){ this->money = _money; } int getMoney(){ cout << "init:"<<initCount<<" money:"<<money <<endl; return money; } Box(){ initCount++; } static int getCount(){ return initCount; } };
输出: init:1 money:1 init:2 money:1
|
静态函数
创建一个静态函数:
static int getCount(){ return initCount; }
|
静态函数不能访问类的非static成员,所以也不能使用this指针。
静态函数是在编译期就存在的,所以不需要类的对象就可以调用:
Box box;
Box::getCount() box.getCount()
|
参考:https://www.w3cschool.cn/cpp/cpp-classes-objects.html
继承
创建一个基类:
class Base { private: int i; public: int j; protected: int k; };
|
继承类,也成为派生类:
class Activity : Base { private:
public: int getJ(){ return j; } int getK(){ return k; }
};
|
派生类能访问基类的public、protected成员,无法访问private成员。
比如上述在获取i成员会报错:
派生类的多种类型:
- 公有继承(public):当一个类派生自公有基类时,基类的公有成员也是派生类的公有成员,基类的保护成员也是派生类的保护成员,基类的私有成员不能直接被派生类访问,但是可以通过调用基类的公有和保护成员来访问。
- 保护继承(protected): 当一个类派生自保护基类时,基类的公有和保护成员将成为派生类的保护成员。
- 私有继承(private):当一个类派生自私有基类时,基类的公有和保护成员将成为派生类的私有成员。
class test: public Base{
};
class test2: protected Base{
};
class test3: private Base{
};
|
多继承
class test4 : Base,test2{
};
class test5 : public Base,private test2,protected test3{
};
|
封装
省略…
多态
同一个类的不同对象在不同情况下有不同的表现
#include <iostream> using namespace std;
class Shape{ private: int length; int width; public: int area(){ cout << "Shape" << endl; } };
class Rectangle : public Shape{ public: int area(){ cout << "Rectangle" << endl; } };
int main(){
Shape *shape; Rectangle rec;
shape = &rec; shape->area();
system("pause"); return 0; }
|
上述代码输出:Shape,也就是执行了Shape类中的area方法,并没有执行派生类方法。
因为 *shape指针定义为Shape类型,area方法在编译器已经存在,所以执行的是编译器时候的area方法。
cpp中引入了虚函数来解决多态问题,virtual
关键字,在基类acre方法中更改:
class Shape{ private: int length; int width; public: virtual int area(){ cout << "Shape" << endl; } };
|
输出结果:Rectangle
除此之外,还可以将virtual函数
设为空实现,成为纯虚函数
:
// 纯虚函数 // virtual int area() = 0;
|
参考:https://www.w3cschool.cn/cpp/cpp-polymorphism.html
接口
cpp中没有接口,只有抽象类,只要一个类有virtual
修饰的纯虚函数,就成为抽象类。
cpp抽象类特点:
- 无法实例化,必须由子类实例化。
- 在实际中为了强调一个类是抽象类,可将该类的构造函数说明为保护(protected)的访问控制权限。
- 派生类必须实现抽象类的纯虚函数,如果没有,则派生类也是一个抽象类.(虚函数则不收影响)