C++ 知识量:19 - 82 - 316
在C++中,可以使用抽象类(abstract class)定义抽象数据类型。抽象类是一种只能被继承不能被实例化的类,它用于定义抽象方法(没有实现的方法)。子类必须实现所有父类中的抽象方法,否则它们也将被视为抽象类。
以下是一个简单的例子,展示了如何定义一个名为Shape的抽象类:
#include <iostream> using namespace std; // 定义抽象类Shape class Shape { public: // 定义抽象方法printArea virtual void printArea() const = 0; }; // 定义派生类Rectangle,并实现printArea方法 class Rectangle : public Shape { public: Rectangle(double w, double h) : width(w), height(h) {} void printArea() const override { cout << "The area of the rectangle is " << width * height << endl; } private: double width, height; }; // 定义派生类Circle,并实现printArea方法 class Circle : public Shape { public: Circle(double r) : radius(r) {} void printArea() const override { cout << "The area of the circle is " << 3.14 * radius * radius << endl; } private: double radius; }; int main() { Rectangle rect(10, 5); // 定义Rectangle对象rect,并传入参数10和5 Circle cir(10); // 定义Circle对象cir,并传入参数10 // 调用printArea方法分别打印矩形和圆的面积 rect.printArea(); // 输出"The area of the rectangle is 50" cir.printArea(); // 输出"The area of the circle is 314.16" return 0; }
在上面的例子中,Shape是一个抽象类,它定义了一个抽象方法printArea。Rectangle和Circle是两个派生类,它们分别实现了printArea方法。在main函数中,定义了一个Rectangle对象rect和一个Circle对象cir,并调用了它们的printArea方法来打印它们的面积。
在C++中,每一个非静态成员函数都有一个隐式的形参,即this指针。this指针是一个指向调用对象自身的指针,它允许成员函数访问调用对象的非静态成员。
对于非静态成员函数,编译器会自动生成一个this指针,并将其作为函数的第一个参数传递。这个this指针的类型是调用对象的类型,而不是函数本身的类型。
例如,对于下面的代码:
class MyClass { public: void myFunction(int x) { // 使用this指针访问对象的非静态成员 this->myMember = x; } private: int myMember; };
在这个例子中,myFunction是一个非静态成员函数,它接受一个整数参数x。在函数体中,使用this指针来访问对象的非静态成员myMember。由于myFunction是一个非静态成员函数,编译器会自动生成一个this指针,并将其作为函数的第一个参数传递。可以通过this->myMember = x;来访问和修改对象的非静态成员myMember。
需要注意的是,this指针是只读的,不能被修改。同时,由于this指针是隐式的,不能在函数参数列表中显式地指定它。
在C++中,const成员函数是一种特殊的成员函数,它可以在const对象上调用,并且保证不会修改对象的状态。
const成员函数的声明语法是在函数参数列表后面加上const关键字。例如:
class MyClass { public: void myFunction() const; // const成员函数声明 };
在const成员函数中,不能修改任何成员变量或调用任何非const成员函数。如果违反了这个规定,编译器将会报错。
const成员函数主要用于以下几个方面:
保证对象的完整性:当一个对象被const修饰时,可以保证它不会被修改,从而保证了对象的完整性。
实现多态性:const成员函数可以用于实现多态性。在基类的const成员函数中调用虚函数时,会自动调用派生类的const成员函数,从而实现了多态性。
提高代码的可读性和可维护性:const成员函数可以清楚地表明该函数不会修改对象的状态,从而提高了代码的可读性和可维护性。
在C++中,类作用域(Class Scope)是指类的成员变量和成员函数的访问范围。在一个类中声明的变量和函数只在该类内部可见,这就是类作用域。
在类外部,只能通过类的对象来访问类的成员变量和成员函数。在类内部,可以直接访问类的成员变量和成员函数,无需使用对象。
类作用域的规则如下:
类成员变量和成员函数只在该类内部可见。
在类内部可以直接访问类的成员变量和成员函数,无需使用对象。
在类外部,只能通过类的对象来访问类的成员变量和成员函数。
如果在类外部定义类的成员函数,必须使用作用域解析运算符(::)来指定该函数属于哪个类。
类的静态成员变量和静态成员函数属于类本身,而不是类的对象,因此可以在类外部直接访问。
以下是一个简单的示例代码:
#include <iostream> class MyClass { public: int myVar; // 类成员变量 void myFunc() { // 类成员函数 std::cout << "This is a class member function." << std::endl; } }; int main() { MyClass obj; // 创建类的对象 obj.myVar = 10; // 访问类的成员变量 obj.myFunc(); // 调用类的成员函数 return 0; }
在C++中,可以使用->或者*操作符从成员函数中返回当前对象的指针。下面是一个定义一个返回this对象的函数的示例:
class MyClass { public: MyClass* getThis() { return this; } };
在这个示例中,getThis()函数返回当前对象的指针。this是一个指向当前对象的指针,它可以在成员函数中使用。通过返回this指针,可以实现一个返回当前对象的函数。
C++中的构造函数是一种特殊的成员函数,它在创建对象时自动调用。构造函数的名称与类的名称相同,并且它不返回任何类型,连void也没有。以下是构造函数的定义形式:
class ClassName { public: ClassName() { // 函数体 } };
在上面的例子中,ClassName是一个类的名称,而ClassName()就是该类的构造函数。当创建ClassName类的对象时,构造函数将自动执行。
构造函数可以有参数,例如:
class ClassName { public: ClassName(int a) { // 函数体 } };
在这个例子中,构造函数ClassName(int a)接受一个int类型的参数。当创建ClassName类的对象时,需要向构造函数传递一个int类型的参数。
构造函数的另一个重要特性是它可以重载。这意味着可以创建多个同名的构造函数,只要它们的参数列表不同。例如:
class ClassName { public: ClassName() { // 函数体 } ClassName(int a) { // 函数体 } };
在这个例子中,有两个同名的构造函数:ClassName()和ClassName(int a)。一个是无参构造函数,另一个是接受一个int类型参数的构造函数。
析构函数(destructor)是一种特殊的成员函数,用于在销毁对象时进行清理工作。在C++中,析构函数的名称为类名前加上波浪号(~)。析构函数没有返回类型,也没有参数,它主要用于释放对象使用的资源,如内存、文件句柄等。
析构函数的调用时机通常是在对象生命周期结束时,例如当对象离开其作用域或被手动删除时。析构函数执行完成后,对象将被销毁。
以下是一个示例,演示如何在C++中声明和定义析构函数:
class MyClass { public: // 构造函数 MyClass() { // 构造函数的实现 } // 析构函数 ~MyClass() { // 析构函数的实现,用于释放资源 } };
需要注意的是,析构函数的调用顺序通常与构造函数的调用顺序相反。即先构造的对象后被销毁,先构造的对象后被销毁。此外,析构函数也可以重载,以便在销毁对象时执行不同的操作。
Copyright © 2017-Now pnotes.cn. All Rights Reserved.
编程学习笔记 保留所有权利
MARK:3.0.0.20240214.P35
From 2017.2.6