欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > c++类和对象---下

c++类和对象---下

2025/1/19 5:53:52 来源:https://blog.csdn.net/2401_87734250/article/details/145157110  浏览:    关键词:c++类和对象---下

文章目录

一、类的静态成员

1.1.静态成员变量:所有对象共享的成员变量。
1.2.静态成员函数:可以访问静态成员变量,但不能访问非静态成员变量。
二、类的继承

2.1.继承:子类继承父类的成员变量和成员函数。
2.2.多态:基类指针或引用可以指向子类对象。
三、类的友元函数和友元类

3.1友元函数:可以访问类的私有成员。
3.2友元类:可以访问类的私有成员。
四、类的封装和数据隐藏

4.1封装:将数据和操作封装在一起,避免外部访问对象的内部细节。
4.2数据隐藏:隐藏类的成员变量,只允许通过类的接口访问。
五、类的重载

5.1运算符重载:重定义运算符的行为。
5.2函数重载:定义多个同名函数,但参数类型或个数不同。
六、类的模板

6.1模板:定义通用的类或函数,可以使用不同的数据类型。
七、类的异常处理

7.1异常处理:捕获和处理程序运行过程中发生的异常。


前言

上一篇文章我们学习了c++类和对象的前半部分,接下来我们来看看类和对象剩下的内容吧


一、类的静态成员

静态成员变量:

      在类中声明的静态成员变量是所有对象共享的。它们属于类本身,而不是类的某个对象。静态成员变量在类的所有对象中都具有相同的值,无论创建了多少个对象,静态成员变量只有一个副本。

      静态成员变量的声明和定义通常在类的外部进行,像全局变量一样。在声明时需要使用 static 关键字。

       静态成员变量可以通过类名加作用域运算符访问,也可以通过对象名加作用域运算符访问。静态成员变量可以在不创建类的对象的情况下访问和修改。

静态成员函数:

       静态成员函数是属于类本身的,而不是类的某个对象。它们不依赖于任何对象的创建,可以直接通过类名调用。

       静态成员函数可以访问和修改静态成员变量,但不能访问非静态成员变量。因为非静态成员变量的值是属于对象的,而静态成员函数没有对象的上下文。

       静态成员函数通常用于执行与类相关的操作,而不需要通过对象来调用。它们可以在不创建类的对象的情况下访问和修改静态成员变量。静态成员函数通常声明和定义在类的内部,但也可以在类的外部定义。

代码演示: 
class Counter {
private:static int count; // 静态成员变量public:static void increaseCount() { // 静态成员函数count++;}static int getCount() { // 静态成员函数return count;}
};int Counter::count = 0; // 静态成员变量初始化int main() {Counter::increaseCount();Counter::increaseCount();Counter::increaseCount();std::cout << "Count: " << Counter::getCount() << std::endl; // Output: Count: 3return 0;
}

       在上面的例子中,count是一个静态成员变量,所有Counter对象共享同一个count变量。通过increaseCount静态成员函数可以增加count的值,通过getCount静态成员函数可以获取count的值。

二、类的继承

       C++中的类继承是一种机制,允许一个类继承另一个类的属性和方法。继承的类称为派生类或子类,被继承的类称为基类或父类。

代码演示: 
#include <iostream>
using namespace std;// 基类
class Animal {
public:virtual void sound() {cout << "动物发出声音" << endl;}
};// 派生类
class Dog : public Animal {
public:void sound() {cout << "汪汪汪" << endl;}
};// 派生类
class Cat : public Animal {
public:void sound() {cout << "喵喵喵" << endl;}
};int main() {Animal* animal;Dog dog;Cat cat;animal = &dog; // 基类指针指向派生类对象animal->sound(); // 调用派生类的函数animal = &cat; // 基类指针指向派生类对象animal->sound(); // 调用派生类的函数return 0;
}

运行上述代码,输出结果为:

汪汪汪
喵喵喵

      在上面的代码中,Animal是基类,Dog和Cat是派生类。Dog和Cat继承了Animal类的成员变量和成员函数。在主函数中,我们使用基类指针animal分别指向Dog和Cat对象,并通过调用sound()函数,输出了相应的声音。

       这就是类的继承和多态的基本用法,通过继承,子类可以继承父类的特性,并且可以通过基类指针或引用来实现多态,即同一种操作可以作用于不同的对象。

三、类的友元函数和友元类

      在C++中,友元函数和友元类是为了实现类的访问控制而引入的特殊机制。

友元函数是指在一个类中,如果把一个全局函数声明为这个类的友元函数,那么这个函数就可以访问该类的私有成员和保护成员,即使在类的外部也可以直接调用该函数来访问类的私有成员和保护成员。

友元类是指在一个类中,如果将另一个类声明为这个类的友元类,那么友元类就可以访问该类的私有成员和保护成员,即使在友元类的定义中也可以直接访问该类的私有成员和保护成员。

       使用友元函数和友元类可以实现一些特殊的访问需求,但是需要注意的是,友元函数和友元类破坏了封装性原则,应该谨慎使用。

代码演示: 
#include <iostream>class MyClass {
private:int privateMember;public:MyClass(int value) {privateMember = value;}friend void friendFunction(MyClass& object); // friend function declarationfriend class FriendClass; // friend class declaration
};void friendFunction(MyClass& object) {std::cout << "Friend function can access private member: " << object.privateMember << std::endl;
}class FriendClass {
public:void displayPrivateMember(MyClass& object) {std::cout << "Friend class can access private member: " << object.privateMember << std::endl;}
};int main() {MyClass obj(42);friendFunction(obj); // calling friend functionFriendClass friendObj;friendObj.displayPrivateMember(obj); // calling friend class methodreturn 0;
}

运行这段代码,输出是:

Friend function can access private member: 42
Friend class can access private member: 42

       在上面的例子中,MyClass类有一个私有成员privateMemberfriendFunction是一个友元函数,它可以访问MyClass类的私有成员。FriendClass是一个友元类,它也可以访问MyClass类的私有成员。

       在main函数中,我们创建了一个MyClass对象obj并传入一个值。然后,我们通过调用友元函数friendFunction来访问privateMember。接着,我们创建了一个FriendClass对象friendObj并调用它的displayPrivateMember方法,它也可以访问privateMember

四、类的封装和数据隐藏

       C++类的封装和数据隐藏是面向对象编程中的重要概念。

      封装是指将数据和操作数据的函数捆绑在一起,形成一个类。通过封装,我们可以将类的实现细节隐藏起来,只暴露必要的接口给外部使用。这样做的好处是可以保护数据的完整性和安全性,同时也方便了代码的维护和重用。

        数据隐藏是指将类的数据成员声明为私有(private)或受保护(protected),只允许通过类的公有(public)成员函数来访问和修改数据。这样做的目的是为了防止外部直接对数据进行非法访问或修改,从而确保数据的一致性和安全性。同时,数据隐藏也可以提高代码的可维护性,因为类的实现细节可以自由改变,而不会影响使用该类的其他代码。

下面是一个简单的示例代码,演示了封装和数据隐藏的使用

代码演示: 

class MyClass {
private:int privateVar; // 私有成员变量,外部无法直接访问public:void setPrivateVar(int value) {privateVar = value;}int getPrivateVar() {return privateVar;}
};int main() {MyClass obj;obj.setPrivateVar(10);int value = obj.getPrivateVar();cout << value << endl; // 输出10,通过类的接口访问私有成员变量return 0;
}

        在上述示例中,私有成员变量privateVar被隐藏起来,外部无法直接访问。我们通过公有的成员函数setPrivateVargetPrivateVar来间接操作和获取私有成员变量的值。这样可以保护私有变量的完整性,同时实现数据隐藏和封装。

五、类的重载

       C++中的重载(Overload)指的是在同一个作用域内定义多个同名的函数,但它们具有不同的参数列表。重载函数可以根据传递给它们的参数的不同来执行不同的操作。

运算符重载:重定义运算符的行为。
代码演示: 
#include <iostream>
using namespace std;class Complex {
private:double real;double imag;
public:Complex(double r, double i):real(r), imag(i) {}Complex operator+(const Complex& c) {double r = this->real + c.real;double i = this->imag + c.imag;return Complex(r, i);}Complex operator-(const Complex& c) {double r = this->real - c.real;double i = this->imag - c.imag;return Complex(r, i);}friend ostream& operator<<(ostream& os, const Complex& c) {os << c.real << " + " << c.imag << "i";return os;}
};int main() {Complex c1(1.0, 2.0);Complex c2(3.0, 4.0);Complex c3 = c1 + c2;Complex c4 = c1 - c2;cout << "c3 = " << c3 << endl;cout << "c4 = " << c4 << endl;return 0;
}
函数重载:定义多个同名函数,但参数类型或个数不同
代码演示: 
#include <iostream>
using namespace std;void print(int num) {cout << "The number is: " << num << endl;
}void print(double num) {cout << "The number is: " << num << endl;
}void print(string str) {cout << "The string is: " << str << endl;
}int main() {int num1 = 123;double num2 = 3.14;string str = "Hello World";print(num1);print(num2);print(str);return 0;
}

六、类的模板

        C++中的类模板是一种泛型编程技术,用于创建通用的类。模板允许我们定义一种通用的类,然后可以根据不同的类型实例化多个具体的类。

代码演示:
template <typename T>
class MyClass {
private:T data;
public:MyClass(T d) : data(d) {}void printData() {std::cout << "Data: " << data << std::endl;}
};
int main() {MyClass<int> obj1(5);obj1.printData(); // 输出: Data: 5MyClass<std::string> obj2("Hello");obj2.printData(); // 输出: Data: Helloreturn 0;
}

       在上面的示例中,MyClass 是一个模板类,<typename T> 表示T是一个类型参数,在使用时可以根据需要指定具体类型。MyClass 的实例化有两种不同的类型:int 和 std::string。每个实例都有自己的 data 成员和 printData() 方法,并且可以根据需要访问和操作这些成员和方法。

七、类的异常处理   

        C++中的异常处理使用try-catch块来捕获和处理异常。try块用于包含可能引发异常的代码,而catch块用于处理捕获的异常。

代码演示: 
#include <iostream>int main() {try {int num1, num2;std::cout << "请输入两个整数:" << std::endl;std::cin >> num1 >> num2;if (num2 == 0) {throw "除数不能为0";}int result = num1 / num2;std::cout << "结果是:" << result << std::endl;} catch (const char* msg) {std::cout << "捕获到异常:" << msg << std::endl;}return 0;
}

       上述代码中,try块包含用户输入两个整数的代码。如果第二个数为0,就会抛出一个字符串类型的异常。catch块会捕获到这个异常,并输出相应的错误信息。

注意:在C++中,异常的类型可以是任何类型,包括内置类型(如int、char等)、标准库类型(如std::string)或自定义类型。你可以根据自己的需要选择合适的异常类型。

       另外,C++还提供了更多的异常处理机制,如try-catch-catch,用来捕获多个类型的异常;以及try-catch-finally,用来在无论异常是否发生都执行一些额外的代码等。


总结

以上就是类和对象的全部内容,后续我会带来更多实用的内容,感兴趣的可以点个赞支持一下!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com