目录
一、引言
二、什么是类?
2.1、成员函数和成员变量
2.2、构造函数和析构函数
2.3、类的成员访问权限
2.4、友元函数和友元类
三、什么是对象?
四、面向对象的三个特点
4.1、封装性
4.2、继承性
4.3、多态性
五、注意事项
C++是一种面向对象的编程语言,类和对象是C++的核心概念之一。在这篇文章中,我们将会介绍类和对象的含义、特点以及如何在C++中使用它们。
类是一种自定义数据类型,它可以包含数据和方法,用于表示某种事物的属性和行为。我们可以将类看做是一个模板,通过实例化类来创建对象。C++中,类的定义通常位于头文件中,如下所示:
class Car {
public:
// 构造函数
Car();
// 带参数的构造函数
Car(string color, int speed, int price);
// 加速方法
void accelerate(int speed);
// 刹车方法
void brake();
private:
// 成员变量
string color;
int speed;
int price;
};
在上面的代码中,我们定义了一个名为“Car”的类,它包含了一个默认构造函数和一个带参数的构造函数,以及两个操作方法。我们还定义了三个私有成员变量,分别代表汽车的颜色、速度和价格。注意,在C++中,类中的成员变量和成员方法默认是私有的,必须通过public关键字来进行公开。
类的定义包含两部分:类头(class head)和类体(class body)。
类头由关键字class及其后面的类名构成,类体由一对大括号括起来{}。类定义后面必须接一个分号或声明加分号。
在类体中,对类的数据成员和成员函数进行了声明,并指定这些成员的访问级别。类体定义了类成员表(class member list)。
成员函数和成员变量是类的两个重要组成部分。成员函数是指在类中定义的函数,而成员变量是指在类中定义的变量。它们的定义方式和普通函数和变量有所不同。
成员函数是在类的内部定义的函数,它们可以访问类中的私有成员和保护成员,也可以访问公有成员。成员函数可以在类的外部通过对象来访问和调用,也可以在类的内部被调用。成员函数的定义方式与普通函数有所不同,通常会在类的定义中给出函数的声明,然后在类的外部定义函数的具体实现。
成员变量是在类的内部定义的变量,它们可以是公有、私有或保护的。公有成员变量可以在类的外部直接访问,私有成员变量只能在类的内部访问,而保护成员变量只能在类的内部或派生类中访问。成员变量的定义方式与普通变量有所不同,通常会在类的定义中给出变量的声明,然后在类的外部定义变量的具体实现。
在C++中,类的成员函数和成员变量都可以使用访问修饰符来控制其访问权限。常见的访问修饰符有public、private和protected。public表示该成员可以在类的外部直接访问,private表示该成员只能在类的内部访问,protected表示该成员只能在类的内部或派生类中访问。访问修饰符必须放在类的定义中,用来指定下面的成员的访问权限。
构造函数是一个特殊的成员函数,它在对象创建时自动调用,并用于初始化对象的数据成员。构造函数的名称必须与类的名称相同,没有返回类型,并且可以有参数。如果没有显式定义构造函数,编译器将为该类自动生成一个默认构造函数。
析构函数也是一个特殊的成员函数,它在对象被销毁时自动调用,并用于清理对象的资源。
构造函数的实现通常用于初始化对象的数据成员,而析构函数的实现通常用于释放对象所使用的资源。例如,以下是一个带有构造函数和析构函数的 MyClass 类的示例:
class MyClass {
private:
int* myInt;
public:
MyClass() {
myInt = new int;
*myInt = 0;
}
~MyClass() {
delete myInt;
}
void setInt(int value) {
*myInt = value;
}
int getInt() {
return *myInt;
}
};
类的成员可以是 public、protected 或 private。默认情况下,类的成员是 private 的,即只能在类的内部访问。public 成员可以在类的外部访问,protected 成员可以在类的派生类中访问。以下是一个示例:
class Rectangle {
private:
double length;
double width;
public:
// 构造函数
Rectangle(double l, double w) {
length = l;
width = w;
}
// 计算面积
double area() {
return length * width;
}
protected:
// 计算周长
double perimeter() {
return 2 * (length + width);
}
};
在这个示例中,length
和 width
是 private 成员,只能在类的内部访问。area
方法是 public 成员,可以在类的外部访问。perimeter
方法是 protected 成员,可以在类的派生类中访问。
友元函数是一种特殊的函数,可以访问类的私有成员。友元函数可以是非成员函数,也可以是其他类的成员函数。友元类是一种特殊的类,可以访问另一个类的私有成员。友元函数和友元类可以在类定义中声明,但不是类的成员。
对象是类的一个实例,可以用来调用类中的方法和访问类中的数据。在C++中,我们可以通过下面的代码来创建一个对象:
Car myCar; // 创建一个名为“myCar”的对象
在上面的代码中,我们创建了一个名为“myCar”的对象,它是一个“Car”类的实例。
封装性是面向对象编程中的一个重要概念,它指的是将数据和操作封装在类中,对外部隐藏具体实现细节,只提供接口。这样可以保证数据的安全性,也可以避免因外部修改导致的程序崩溃。
在C++中,我们可以通过访问控制关键字public、private、protected来实现封装性。public成员可以被类外部访问,private成员只能被类内部访问,protected成员既可以被类内部访问也可以被派生类访问。
class Car {
public:
// 构造函数
Car();
// 带参数的构造函数
Car(string color, int speed, int price);
// 加速方法
void accelerate(int speed);
// 刹车方法
void brake();
private:
// 成员变量
string color;
int speed;
int price;
};
在上面的代码中,color、speed、price成员变量是private的,只能在类内被访问。
继承性是面向对象编程中另一个重要的概念,它指的是通过一个已有的类来创建一个新的类,新类可以继承已有类的属性和方法。已有类叫做父类或基类,新类叫做子类或派生类。继承可以提高代码的重用性,减少代码的冗余度。
在C++中,我们可以使用“:”符号来继承父类,如下所示:
class SportsCar : public Car {
public:
// 构造函数
SportsCar();
// 带参数的构造函数
SportsCar(string color, int speed, int price, int turbo);
// 加速方法
void turboAccelerate();
private:
// 成员变量
int turbo;
};
在上面的代码中,我们定义了一个名为“SportsCar”的子类,它继承了“Car”类的所有属性和方法,并添加了一个名为“turbo”的成员变量和一个名为“turboAccelerate”的方法。
多态性是面向对象编程中的另一个重要概念,它指的是同一操作在不同对象上有不同的表现形式。简单来说,就是不同对象对同一消息作出不同的响应。多态性可以增强代码的灵活性和可扩展性。
在C++中,我们可以通过虚函数来实现多态性,如下所示:
class Car {
public:
// 构造函数
Car();
// 加速方法
virtual void accelerate(int speed);
// 刹车方法
virtual void brake();
};
class SportsCar : public Car {
public:
// 构造函数
SportsCar();
// 加速方法
void accelerate(int speed) override;
// 刹车方法
void brake() override;
};
在上面的代码中,我们将“Car”类的加速方法和刹车方法声明为虚函数,然后在“SportsCar”子类中重新定义了这两个方法。这样,在调用“SportsCar”对象的加速方法和刹车方法时,会根据实际对象类型调用相应的方法。
在使用 C++ 类和对象时,我们应该注意以下几点:
1、类的设计应该尽量简单明了,只包含必要的成员和方法,避免过度设计和复杂度过高。
2、类成员的访问控制应该根据需要进行设置,一般来说,私有成员应该只在类内部使用,而公有成员可以被外部访问。
3、继承应该用于实现类之间的一般化关系,而不是简单的代码重用。同时,应该注意避免多层继承和菱形继承等问题。
4、多态应该在需要时使用,可以通过虚函数实现。虚函数可以用来声明一个基类成员函数,使其在派生类中可以被重写。
5、在使用指针访问类成员时,要注意指针是否为空,否则可能会导致程序崩溃或出现不可预期的结果。
除了上述注意事项,还应该遵循良好的编程规范和风格,例如命名规范、代码缩进、注释等。同时,也应该注意程序的可读性和可维护性,避免出现代码冗长、复杂度过高等问题。