做老师讲课视频的教育网站,广东旅游网站建设,徐州做网站,广东网络营销是什么C知识点复习下 一、面向对象编程#xff1a;深入理解类与对象1.类的定义和访问2.this指针3.构造函数与析构函数4.重载和拷贝构造函数5.常成员和静态成员6.友元 二、运算符重载1. 规则2. 成员或友元重载2.1 例子#xff1a;成员函数重载2.2 例子#xff1a;友元函数重载 3. 类… C知识点复习下 一、面向对象编程深入理解类与对象1.类的定义和访问2.this指针3.构造函数与析构函数4.重载和拷贝构造函数5.常成员和静态成员6.友元 二、运算符重载1. 规则2. 成员或友元重载2.1 例子成员函数重载2.2 例子友元函数重载 3. 类类型转换3.1 构造函数类类型转换3.2 转换运算符类类型转换 三、继承1. 类之间的访问控制1.1 公有继承1.2 私有继承1.3 保护继承 2. 基类初始化3. 多继承4. 虚继承 四、虚函数与多态性1. 引言2. 虚函数的概念3. 静态联编与动态联编3.1 静态联编3.2 动态联编 4. 类指针与多态性5. 纯虚函数与抽象类5.1 纯虚函数5.2 抽象类 五、模板1. 引言2. 函数模板3. 类模板4. 模板重载 一、面向对象编程深入理解类与对象
在面向对象编程Object-Oriented Programming简称OOP中类与对象是基本概念对于理解和设计复杂的软件系统至关重要。包括类的定义和访问、this指针、构造函数、析构函数、重载和拷贝构造函数、常成员和静态成员以及友元。
1.类的定义和访问
在C中类是一种用户自定义的数据类型用于封装数据和相关操作。以下是一个简单的类的定义和对象的访问的示例
// 类的定义
class Person {
public:// 成员变量string name;int age;// 成员函数void displayInfo() {cout Name: name , Age: age endl;}
};// 对象的访问
int main() {// 创建对象Person person1;// 访问对象的成员person1.name John;person1.age 25;person1.displayInfo();return 0;
}2.this指针
在类的成员函数中this指针用于指向当前对象的地址以便访问对象的成员。这在类的方法中经常用于区分成员变量和参数变量。
class Point {
private:int x, y;public:void setCoordinates(int x, int y) {// 使用this指针来区分成员变量和参数变量this-x x;this-y y;}
};3.构造函数与析构函数
构造函数在对象创建时调用用于初始化对象的成员变量。析构函数在对象销毁时调用用于清理资源。以下是一个简单的例子
class Car {
public:// 构造函数Car() {cout Car is created. endl;}// 析构函数~Car() {cout Car is destroyed. endl;}
};4.重载和拷贝构造函数
重载允许在同一作用域中定义多个相同名称的函数但参数列表不同。拷贝构造函数用于在对象创建时从另一个对象中拷贝值。
class Complex {
public:// 重载构造函数Complex(int real, int imag) {this-real real;this-imag imag;}// 拷贝构造函数Complex(const Complex obj) {real obj.real;imag obj.imag;}private:int real, imag;
};5.常成员和静态成员
常成员是指在成员函数中不能修改成员变量的成员通过关键字const实现。静态成员是类的所有对象共享的成员。
class Circle {
public:// 静态成员static int count;// 常成员函数void displayRadius() const {// 不可修改成员变量// radius 5; // 错误cout Radius: radius endl;}private:int radius;
};// 初始化静态成员
int Circle::count 0;6.友元
友元允许一个外部类或函数访问另一个类的私有成员。这提供了灵活性但也要慎用因为可能破坏封装性。
class Square;class Rectangle {
private:int length, width;public:Rectangle(int l, int w) : length(l), width(w) {}// 友元函数friend bool isSquare(Rectangle, Square);
};class Square {
private:int side;public:Square(int s) : side(s) {}// 友元函数的实现friend bool isSquare(Rectangle, Square);
};// 友元函数
bool isSquare(Rectangle r, Square s) {return (r.length s.side) (r.width s.side);
}二、运算符重载
1. 规则
在C中运算符重载必须遵循一些规则以确保正确和一致的行为。
重载的运算符必须至少有一个操作数是用户定义的类型。不能改变运算符的优先级或结合性。不能创建新的运算符。只能重载已存在的运算符。不能改变运算符的含义。
2. 成员或友元重载
运算符重载可以通过成员函数或友元函数来实现。对于成员函数重载通常将运算符重载作为类的成员函数这样它至少有一个操作数是调用对象。对于友元函数它可以访问类的私有成员但不是类的成员。
2.1 例子成员函数重载
class Complex {
public:Complex operator(const Complex other) const {Complex result;result.real this-real other.real;result.imaginary this-imaginary other.imaginary;return result;}private:double real;double imaginary;
}2.2 例子友元函数重载
class Complex {
public:friend Complex operator(const Complex c1, const Complex c2) {Complex result;result.real c1.real c2.real;result.imaginary c1.imaginary c2.imaginary;return result;}private:double real;double imaginary;
}3. 类类型转换
类类型转换是将一个类类型转换为另一个类类型的过程。在C中有两种类类型转换构造函数和转换运算符。
3.1 构造函数类类型转换
class Distance {
public:Distance(int meters) : meters(meters) {}private:int meters;
};class Speed {
public:Speed(const Distance distance) {// Conversion logic from distance to speed}private:// Other members
};3.2 转换运算符类类型转换
class Rational {
public:operator double() const {return static_castdouble(numerator) / denominator;}private:int numerator;int denominator;
}三、继承
1. 类之间的访问控制
在C中继承提供了三种访问控制方式公有继承、私有继承和保护继承。这些方式决定了派生类如何访问基类的成员。
1.1 公有继承
公有继承是最常见的一种方式它允许派生类访问基类的公有成员但不能访问基类的私有成员。
class Base {
public:int publicMember;
private:int privateMember;
};class Derived : public Base {// 可以访问publicMember但不能访问privateMember
};1.2 私有继承
私有继承使得基类的公有和保护成员在派生类中变为私有成员因此不能被外部访问。
class Base {
public:int publicMember;
protected:int protectedMember;
};class Derived : private Base {// publicMember和protectedMember在Derived中都变成私有成员
};1.3 保护继承
保护继承允许派生类访问基类的公有和保护成员但它们在派生类中仍然是保护成员。
class Base {
public:int publicMember;
protected:int protectedMember;
};class Derived : protected Base {// 可以访问publicMember和protectedMember
};2. 基类初始化
在派生类的构造函数中需要正确初始化基类的部分。这可以通过使用初始化列表来完成。
class Base {
public:Base(int value) : data(value) {}
private:int data;
};class Derived : public Base {
public:Derived(int value) : Base(value), derivedData(value * 2) {}
private:int derivedData;
};3. 多继承
多继承允许一个派生类同时继承多个基类。在多继承中需要注意解决潜在的命名冲突问题。
class Base1 {
public:void display() { /* 实现 */ }
};class Base2 {
public:void display() { /* 实现 */ }
};class Derived : public Base1, public Base2 {
public:// 需要解决display()的命名冲突using Base1::display;
};4. 虚继承
虚继承用于解决菱形继承问题其中一个派生类通过两个不同的路径继承同一个基类。使用虚继承可以确保只有一份基类的实例。
class Base {
public:int data;
};class Derived1 : virtual public Base {// 实现
};class Derived2 : virtual public Base {// 实现
};class DiamondDerived : public Derived1, public Derived2 {// 只有一份Base的实例
};四、虚函数与多态性
1. 引言
在面向对象的程序设计中虚函数和多态性是C中强大而灵活的特性。它们使得代码更加可维护、可扩展并提高了代码的复用性。多态性的实现方式包括静态联编、类指针、动态联编、纯虚函数和抽象类。
2. 虚函数的概念
在C中虚函数通过将关键字virtual添加到基类函数声明中来实现。虚函数的存在使得在运行时能够根据对象的实际类型调用相应的函数。
class Shape {
public:virtual void draw() {// 基类中的虚函数// 具体实现由派生类提供}
};3. 静态联编与动态联编
3.1 静态联编
静态联编是指在编译时确定调用哪个函数这是C中默认的行为。对于非虚函数编译器在编译时就能确定要调用的函数。
class Base {
public:void print() {std::cout Base class std::endl;}
};class Derived : public Base {
public:void print() {std::cout Derived class std::endl;}
};int main() {Derived derivedObj;derivedObj.print(); // 编译时确定调用Derived::print()return 0;
}3.2 动态联编
动态联编是通过使用虚函数来实现的它允许在运行时确定要调用的函数。使用基类指针或引用调用虚函数会触发动态联编。
int main() {Base* basePtr new Derived();basePtr-print(); // 运行时确定调用Derived::print()delete basePtr;return 0;
}4. 类指针与多态性
通过使用基类指针或引用可以实现对派生类对象的多态操作。
void drawShape(Shape* shape) {shape-draw(); // 调用派生类中相应的draw函数
}int main() {Circle circle;Square square;drawShape(circle); // 多态调用Circle::draw()drawShape(square); // 多态调用Square::draw()return 0;
}5. 纯虚函数与抽象类
5.1 纯虚函数
纯虚函数是在基类中声明的虚函数但没有提供具体实现。包含纯虚函数的类被称为抽象类。
class AbstractShape {
public:virtual void draw() 0; // 纯虚函数
};class ConcreteShape : public AbstractShape {
public:void draw() override {// 具体实现}
};5.2 抽象类
抽象类不能实例化但可以作为接口类定义派生类必须实现的接口。
void drawAllShapes(std::vectorAbstractShape* shapes) {for (auto shape : shapes) {shape-draw(); // 多态调用各个派生类的draw函数}
}int main() {Circle circle;Square square;ConcreteShape concreteShape;std::vectorAbstractShape* shapes {circle, square, concreteShape};drawAllShapes(shapes);return 0;
}五、模板
1. 引言
C模板是一种强大的编程工具它允许在编写代码时使用泛型类型。泛型编程使得代码更加灵活和可重用因为它允许编写与特定数据类型无关的通用代码。在C中主要有两种类型的模板函数模板和类模板。此外C还支持模板的重载使得我们可以根据不同的需求定义多个模板版本。
2. 函数模板
函数模板是一种允许定义通用函数的机制可以处理不同类型的参数。下面是一个简单的函数模板示例
template typename T
T add(T a, T b) {return a b;
}int main() {int result_int add(5, 10);double result_double add(3.5, 2.7);return 0;
}在上面的例子中add 函数是一个模板函数可以处理不同类型的参数包括整数和浮点数。
3. 类模板
类模板允许我们定义通用类可以处理不同类型的数据。以下是一个简单的类模板示例
template typename T
class Pair {
public:Pair(T first, T second) : first_(first), second_(second) {}T getFirst() const {return first_;}T getSecond() const {return second_;}private:T first_;T second_;
};int main() {Pairint intPair(1, 2);Pairdouble doublePair(3.5, 2.7);return 0;
}在这个例子中Pair 类模板可以处理不同类型的数据例如 int 和 double。
4. 模板重载
模板重载允许我们定义多个模板版本以处理不同类型或不同数量的参数。以下是一个模板重载的示例
template typename T
T multiply(T a, T b) {return a * b;
}template typename T, typename U
U multiply(T a, U b) {return a * b;
}int main() {int result1 multiply(5, 10);double result2 multiply(3.5, 2.7);return 0;
}在这个例子中有两个版本的 multiply 函数分别处理相同类型和不同类型的参数。