- 类的成员访问控制:
public
: 公有成员,在类的内部和外部都可以访问。private
: 私有成员,只有在类的内部可以访问,外部无法访问。protected
: 受保护成员,类的内部可以访问,继承类可以访问,外部无法访问。
-
class Rectangle { public: // 公有成员 double length; double width; private: // 私有成员 double area; protected: // 受保护成员 double perimeter; }; int main() { Rectangle r; r.length = 5; // 可以访问公有成员 length // r.area = 25; // 错误,无法访问私有成员 area // r.perimeter = 20; // 错误,无法访问受保护成员 perimeter return 0; }
- 类的静态成员函数和静态成员变量:
- 静态成员函数:属于整个类,而不是对象实例。可以直接通过类名调用,不需要通过对象。
- 静态成员变量:属于整个类,而不是对象实例。在内存中只有一份拷贝,所有对象共享。
-
class Counter { private: static int count; // 静态成员变量,表示计数器的值 public: static void increment() { // 静态成员函数,用于增加计数器的值 count++; } static int getCount() { // 静态成员函数,用于获取计数器的值 return count; } }; int Counter::count = 0; // 静态成员变量初始化 int main() { Counter::increment(); // 调用静态成员函数 Counter::increment(); int count = Counter::getCount(); // 调用静态成员函数 return 0; }
- 类的友元函数:
- 友元函数可以访问类的私有成员。通过在类中声明友元函数并在函数外部进行定义来实现。
-
class Rectangle { private: double length; double width; public: Rectangle(double _length, double _width) : length(_length), width(_width) {} friend double calculateArea(const Rectangle& rect); // 声明友元函数 }; double calculateArea(const Rectangle& rect) { // 定义友元函数 return rect.length * rect.width; // 可以访问私有成员 length 和 width } int main() { Rectangle r(5, 3); double area = calculateArea(r); // 调用友元函数 return 0; }
- 类的继承:
- 继承是面向对象编程的一个重要概念,它允许一个类(子类)从另一个类(基类)继承属性和行为。
- 子类可以访问基类的公有和受保护成员,但不能访问私有成员。
-
class Animal { protected: string name; public: Animal(const string& _name) : name(_name) {} void eat() { cout << name << " is eating." << endl; } }; class Dog : public Animal { public: Dog(const string& _name) : Animal(_name) {} void bark() { cout << name << " is barking." << endl; } }; int main() { Dog dog("Buddy"); dog.eat(); // 继承了基类的 eat() 函数 dog.bark(); // 子类的成员函数 return 0; }
- 多态性(Polymorphism):
- 多态性是面向对象编程的一个重要特征,它允许使用基类指针或引用来引用派生类对象,并根据实际对象的类型来调用相应的成员函数。
- 多态性通过虚函数(virtual function)实现。在基类中声明为虚函数,在派生类中进行重写(override)。
-
class Animal { public: virtual void makeSound() { cout << "Animal is making a sound." << endl; } }; class Dog : public Animal { public: void makeSound() override { cout << "Dog is barking." << endl; } }; class Cat : public Animal { public: void makeSound() override { cout << "Cat is meowing." << endl; } }; int main() { Animal* animal1 = new Dog(); Animal* animal2 = new Cat(); animal1->makeSound(); // 调用 Dog 的 makeSound() animal2->makeSound(); // 调用 Cat 的 makeSound() delete animal1; delete animal2; return 0; }
- 抽象类和纯虚函数:
- 抽象类是一个不能被实例化的类,它的目的是作为其他类的基类提供接口定义。
- 纯虚函数是在基类中声明为虚函数的函数,并且没有任何定义,要求派生类必须实现该函数。
-
class Shape { public: virtual double getArea() = 0; // 纯虚函数 void printArea() { cout << "Area: " << getArea() << endl; } }; class Circle : public Shape { private: double radius; public: Circle(double _radius) : radius(_radius) {} double getArea() override { return 3.14159 * radius * radius; } }; class Rectangle : public Shape { private: double length; double width; public: Rectangle(double _length, double _width) : length(_length), width(_width) {} double getArea() override { return length * width; } }; int main() { Shape* shape1 = new Circle(5); Shape* shape2 = new Rectangle(3, 4); shape1->printArea(); // 调用 Circle 的 getArea() shape2->printArea(); // 调用 Rectangle 的 getArea() delete shape1; delete shape2; return 0; }
- 类的构造函数和析构函数:
- 构造函数是一种特殊的成员函数,在创建对象时自动调用,用于初始化对象的数据成员。
- 析构函数也是一种特殊的成员函数,在对象被销毁时自动调用,用于清理对象的资源。
-
class Rectangle { private: double length; double width; public: Rectangle(double _length, double _width) : length(_length), width(_width) { cout << "Rectangle constructor is called." << endl; } ~Rectangle() { cout << "Rectangle destructor is called." << endl; } void printArea() { cout << "Area: " << length * width << endl; } }; int main() { Rectangle r(5, 3); // 创建对象时调用构造函数 r.printArea(); // 调用成员函数 // 对象超出作用域时调用析构函数 return 0; }
- 拷贝构造函数:
- 拷贝构造函数是一种特殊的构造函数,用于通过已有对象创建新对象。
- 默认情况下,C++会提供一个浅拷贝的拷贝构造函数,只是简单地拷贝数据成员的值。
- 当类的数据成员中存在指针等动态内存分配的情况时,通常需要自定义深拷贝的拷贝构造函数,避免浅拷贝带来的问题。
-
class String { private: char* buffer; public: String(const char* _buffer) { int length = strlen(_buffer); buffer = new char[length + 1]; strcpy(buffer, _buffer); } String(const String& other) { int length = strlen(other.buffer); buffer = new char[length + 1]; strcpy(buffer, other.buffer); } ~String() { delete[] buffer; } }; int main() { String s1("Hello"); String s2 = s1; // 使用拷贝构造函数创建新对象 // 对象超出作用域时调用析构函数 return 0; }
- 类的运算符重载:
- 运算符重载是一种特殊的成员函数,用于改变运算符的行为,允许在类对象上使用运算符操作。
- 通过重载运算符,可以使类对象的操作行为更加直观和灵活。
-
class Complex { private: double real; double imaginary; public: Complex(double _real, double _imaginary) : real(_real), imaginary(_imaginary) {} Complex operator+(const Complex& other) { double newReal = real + other.real; double newImaginary = imaginary + other.imaginary; return Complex(newReal, newImaginary); } }; int main() { Complex c1(2.5, 1.5); Complex c2(1.5, 2.5); Complex c3 = c1 + c2; // 使用重载的 + 运算符 return 0; }
- 静态成员变量和静态成员函数:
- 静态成员变量是类的所有对象共享的变量,不需要通过对象来访问,可以直接使用类名来访问。
- 静态成员函数是类的所有对象共享的函数,只能访问静态成员变量和其他静态成员函数,不可以访问非静态成员变量和非静态成员函数。
-
class MyClass { public: static int count; // 静态成员变量 static void printCount() { cout << "Count: " << count << endl; } }; int MyClass::count = 0; // 静态成员变量的初始化需要在类外进行 int main() { MyClass::count = 5; // 直接使用类名访问静态成员变量 MyClass::printCount(); // 使用类名调用静态成员函数 return 0; }
- 友元类和友元函数:
- 友元类是在类的声明中声明的一个类,它可以访问类的私有成员。
- 友元函数是在类的声明中声明的一个函数,它可以访问类的私有成员。
-
class Car { private: string brand; public: Car(const string& _brand) : brand(_brand) {} friend class Mechanic; // 声明友元类 friend void repairCar(Car& car); // 声明友元函数 }; class Mechanic { public: void fixCar(Car& car) { cout << "Fixing car: " << car.brand << endl; } }; void repairCar(Car& car) { cout << "Repairing car: " << car.brand << endl; } int main() { Car car("BMW"); Mechanic mechanic; mechanic.fixCar(car); // 友元类的成员函数调用 repairCar(car); // 友元函数调用 return 0; }
- 类的访问修饰符:
- 类的成员变量和成员函数都可以通过访问修饰符指定其访问级别。
public
:公有成员,可以在类内外访问。protected
:受保护成员,可以在类内和派生类中访问。private
:私有成员,只能在类内访问。-
class Person { public: string name; // 公有成员 protected: int age; // 受保护成员 private: double salary; // 私有成员 }; int main() { Person person; person.name = "Alice"; // 可以访问公有成员 // person.age = 25; // 不可以访问受保护成员 // person.salary = 5000; // 不可以访问私有成员 return 0; }
- 继承:
- 继承是一种面向对象编程的机制,可以让一个类(称为派生类)获得另一个类(称为基类)的成员变量和成员函数。
- 派生类可以扩展基类的功能,也可以重新定义基类的函数(即重写)。
- 继承有三种类型:公有继承(public inheritance)、私有继承(private inheritance)和保护继承(protected inheritance)。
-
class Animal { public: void eat() { cout << "Animal is eating." << endl; } }; class Cat : public Animal { // 公有继承 public: void meow() { cout << "Cat is meowing." << endl; } }; class Lion : protected Cat { // 保护继承 public: void roar() { cout << "Lion is roaring." << endl; } }; int main() { Animal animal; animal.eat(); // Animal类的成员函数 Cat cat; cat.eat(); // Animal类的成员函数 cat.meow(); // Cat类的成员函数 Lion lion; lion.eat(); // 通过Cat类间接调用Animal类的成员函数 lion.meow(); // 通过Cat类间接调用Cat类的成员函数 lion.roar(); // Lion类的成员函数 return 0; }
- 多态:
- 多态是面向对象编程的一种特性,指的是子类可以表现出与父类不同的行为。
- 多态有两种形式:静态多态(通过函数重载和运算符重载实现)和动态多态(通过虚函数实现)。
- 在C++中,通过使用
virtual
关键字来声明虚函数。 -
class Shape { public: virtual void draw() { cout << "Shape is drawing." << endl; } }; class Rectangle : public Shape { public: void draw() override { cout << "Rectangle is drawing." << endl; } }; class Circle : public Shape { public: void draw() override { cout << "Circle is drawing." << endl; } }; int main() { Shape* shape1 = new Rectangle(); shape1->draw(); // 动态绑定,调用Rectangle类的成员函数 Shape* shape2 = new Circle(); shape2->draw(); // 动态绑定,调用Circle类的成员函数 delete shape1; delete shape2; return 0; }
- 抽象类和纯虚函数:
- 抽象类是不能被实例化的类,只能被用作其他类的基类。
- 抽象类中包含纯虚函数,纯虚函数没有实际的实现,派生类必须为纯虚函数提供实现。
- 抽象类可以用来定义接口,派生类必须实现这些接口。
-
class Shape { public: virtual void draw() = 0; // 纯虚函数,没有实际实现 }; class Rectangle : public Shape { public: void draw() { cout << "Rectangle is drawing." << endl; } }; class Circle : public Shape { public: void draw() { cout << "Circle is drawing." << endl; } }; int main() { Shape* shape1 = new Rectangle(); shape1->draw(); // 动态绑定,调用Rectangle类的成员函数 Shape* shape2 = new Circle(); shape2->draw(); // 动态绑定,调用Circle类的成员函数 delete shape1; delete shape2; return 0; }
- 虚析构函数:
- 如果在一个基类中定义了虚析构函数,则派生类中的析构函数也应该被声明为虚析构函数。
- 使用虚析构函数可以确保当删除一个指向派生类对象的基类指针时,派生类的析构函数被正确调用。
-
class Shape { public: virtual ~Shape() { cout << "Shape destructor." << endl; } }; class Rectangle : public Shape { public: ~Rectangle() override { cout << "Rectangle destructor." << endl; } }; int main() { Shape* shape = new Rectangle(); delete shape; // 动态绑定,调用Rectangle类的析构函数 return 0; }
- 类模板(泛型):
- 类模板是一种通用的类定义,可以用于创建具有不同数据类型的类。
- 类模板使用
template
关键字来声明,可以通过占位符类型来表示泛型。 -
template<typename T> class Stack { private: vector<T> elements; public: void push(const T& element) { elements.push_back(element); } void pop() { elements.pop_back(); } const T& top() const { return elements.back(); } }; int main() { Stack<int> intStack; intStack.push(1); intStack.push(2); intStack.push(3); cout << intStack.top() << endl; // 输出:3 Stack<string> stringStack; stringStack.push("Hello"); stringStack.push("World"); cout << stringStack.top() << endl; // 输出:World return 0; }
- 类模板特化:
- 可以通过特化来在特定的数据类型上使用特定的实现逻辑。
- 类模板的特化是在类模板的声明之后、类模板成员函数定义之前进行的。
-
template<typename T> class Stack { private: vector<T> elements; public: void push(const T& element) { elements.push_back(element); } void pop() { elements.pop_back(); } const T& top() const { return elements.back(); } }; template<> class Stack<string> { // 类模板特化 private: vector<string> elements; public: void push(const string& element) { elements.push_back("Special: " + element); } void pop() { elements.pop_back(); } const string& top() const { return elements.back(); } }; int main() { Stack<int> intStack; intStack.push(1); intStack.push(2); intStack.push(3); cout << intStack.top() << endl; // 输出:3 Stack<string> stringStack; stringStack.push("Hello"); stringStack.push("World"); cout << stringStack.top() << endl; // 输出:Special: World return 0; }
- 静态成员:
- 静态成员是类的成员,它们与类本身相关,而不是与类的实例相关。
- 静态成员可以是静态变量或静态函数,在类中只有一份副本,可以在不创建类的实例的情况下访问。
-
class MyClass { public: static int count; // 静态变量声明 static void increment() { // 静态函数定义 count++; } }; int MyClass::count = 0; // 静态变量定义和初始化 int main() { MyClass::increment(); // 调用静态函数,修改静态变量 cout << MyClass::count << endl; // 输出:1 MyClass::count = 10; // 直接访问和修改静态变量 cout << MyClass::count << endl; // 输出:10 MyClass obj1; obj1.count++; // 通过实例对象访问和修改静态变量 cout << obj1.count << endl; // 输出:11 MyClass obj2; cout << obj2.count << endl; // 输出:11(因为静态变量只有一份副本) return 0; }
- 友元类和友元函数:
- 友元类和友元函数是在类之外声明的,它们可以访问类的私有成员。
- 友元类可以访问该类的所有成员(包括私有成员),而友元函数只能访问类的私有成员。
-
class MyClass; class FriendClass { // 友元类 public: void printCount(MyClass& obj) { cout << obj.count << endl; // 访问私有成员 } }; class MyClass { private: int count = 10; friend FriendClass; // 声明FriendClass为友元类 friend void printCount(MyClass& obj) { // 声明printCount()为友元函数 cout << obj.count << endl; // 访问私有成员 } }; int main() { MyClass obj; FriendClass friendObj; friendObj.printCount(obj); // 输出:10(通过友元类访问私有成员) printCount(obj); // 输出:10(通过友元函数访问私有成员) return 0; }
- 拷贝构造函数:
- 拷贝构造函数是一种特殊的构造函数,用于用一个对象初始化另一个对象。
- 如果没有显式定义拷贝构造函数,编译器会自动生成一个默认的拷贝构造函数。
-
class MyClass { public: int data; // 默认的拷贝构造函数 MyClass(int d) : data(d) {} }; int main() { MyClass obj1(10); MyClass obj2 = obj1; // 使用拷贝构造函数初始化 cout << obj2.data << endl; // 输出:10 return 0; }
- 移动构造函数:
- 移动构造函数是C++11引入的一项特性,用于在对象之间进行资源的快速移动或转移。
- 移动构造函数通常使用右值引用参数(&&)来接收要移动的对象。
-
class MyString { private: char* data; public: MyString(const char* str) { // 分配内存、拷贝字符串等初始化操作 } // 移动构造函数 MyString(MyString&& other) : data(other.data) { other.data = nullptr; // 将原对象的资源指针设置为空,防止原对象析构时释放资源 } // 其他成员函数和析构函数的实现... }; int main() { MyString str1("Hello"); MyString str2 = std::move(str1); // 使用移动构造函数初始化,str1的资源会被转移到str2 // 此时str1不再持有资源,str2持有资源 return 0; }
- 成员初始化列表:
- 成员初始化列表用于在构造函数中初始化类的成员变量。
- 在成员初始化列表中初始化成员变量比在构造函数体中进行赋值操作更高效。
-
class MyClass { private: int number; string name; public: // 成员初始化列表初始化成员变量 MyClass(int n, const string& str) : number(n), name(str) {} // 其他成员函数和析构函数的实现... }; int main() { MyClass obj(10, "Hello"); // 此时obj的number成员变量为10,name成员变量为"Hello" return 0; }
- const 成员函数:
- const 成员函数是指在函数声明和定义中都被标记为 const 的成员函数。
- const 成员函数承诺不会修改对象的成员变量。
-
class MyClass { private: int data; public: MyClass(int d) : data(d) {} int getData() const { // const 成员函数 // data = 10; // 错误,不能修改成员变量 return data; } }; int main() { const MyClass obj(10); cout << obj.getData() << endl; // 输出:10(const对象可以调用const成员函数) return 0; }
- 静态成员函数:
- 静态成员函数是在类中声明为静态的成员函数。
- 静态成员函数没有访问隐式的 this 指针,因此不能访问非静态成员变量和非静态成员函数。
-
class MyClass { public: static int getNumber() { return 10; } }; int main() { cout << MyClass::getNumber() << endl; // 输出:10(通过类名调用静态成员函数) return 0; }
- 类模板特化成员函数:
- 类模板特化成员函数是在类模板特化中定义的特定数据类型的成员函数。
-
template<typename T> class Stack { private: vector<T> elements; public: void push(const T& element) { elements.push_back(element); } void pop() { elements.pop_back(); } const T& top() const { return elements.back(); } // 类模板特化的成员函数 void printSize() { cout << "Size: " << elements.size() << endl; } }; template<> void Stack<string>::printSize() { // 类模板特化成员函数的定义 cout << "Special Size: " << elements.size() << endl; } int main() { Stack<int> intStack; intStack.push(1); intStack.push(2); intStack.printSize(); // 输出:Size: 2 Stack<string> stringStack; stringStack.push("Hello"); stringStack.push("World"); stringStack.printSize(); // 输出:Special Size: 2 return 0; }
- 继承:
- 继承是面向对象编程中的重要概念,它允许一个类从另一个类派生,并获取父类的属性和方法。
- 派生类可以扩展或修改继承的成员,并可以添加自己的成员。
- 继承关系可以分为公有继承、私有继承和受保护继承。
-
class Shape { protected: int width; int height; public: Shape(int w, int h) : width(w), height(h) {} void printArea() const { cout << "Area: " << calculateArea() << endl; } virtual int calculateArea() const { return 0; } }; class Rectangle : public Shape { public: Rectangle(int w, int h) : Shape(w, h) {} int calculateArea() const override { return width * height; } }; class Triangle : public Shape { public: Triangle(int w, int h) : Shape(w, h) {} int calculateArea() const override { return width * height / 2; } }; int main() { Rectangle rect(5, 3); rect.printArea(); // 输出:Area: 15 Triangle tri(4, 6); tri.printArea(); // 输出:Area: 12 return 0; }
- 多继承:
- 多继承是指一个派生类可以从多个基类中继承属性和方法。
-
class Animal { public: void eat() { cout << "Animal eating..." << endl; } }; class Flyable { public: void fly() { cout << "Flying..." << endl; } }; class Bird : public Animal, public Flyable { public: void sing() { cout << "Bird singing..." << endl; } }; int main() { Bird bird; bird.eat(); // 输出:Animal eating... bird.fly(); // 输出:Flying... bird.sing(); // 输出:Bird singing... return 0; }
- 虚函数和纯虚函数:
- 虚函数是在基类中声明为虚函数的成员函数,它可以在派生类中被覆盖(重写)。
- 纯虚函数是在基类中声明为纯虚函数的虚函数,它不需要提供实现,而是由派生类实现。
- 包含纯虚函数的类称为抽象类,不能实例化对象。
-
class Shape { public: virtual int calculateArea() const = 0; // 纯虚函数,需要在派生类中实现 void printArea() const { cout << "Area: " << calculateArea() << endl; // 调用纯虚函数 } }; class Rectangle : public Shape { private: int width; int height; public: Rectangle(int w, int h) : width(w), height(h) {} int calculateArea() const override { return width * height; } }; int main() { // Shape shape; // 错误,抽象类无法实例化对象 Rectangle rect(5, 3); rect.printArea(); // 输出:Area: 15 return 0; }
- 友元函数:
- 友元函数是在类中声明为友元的非成员函数,它可以访问类的私有成员。
- 友元函数可以在类内声明,在类外进行定义。
-
class MyClass { private: int data; public: MyClass(int d) : data(d) {} friend void printData(const MyClass& obj); // 声明友元函数 }; void printData(const MyClass& obj) { cout << "Data: " << obj.data << endl; // 可以访问私有成员data } int main() { MyClass obj(10); printData(obj); // 输出:Data: 10 return 0; }
- 类型转换运算符:
- 类型转换运算符是一种特殊的成员函数,它用于将对象从一种类型转换为另一种类型。
- 类型转换运算符可以是任意类型(基本类型或类类型)。
-
class MyInteger { private: int value; public: MyInteger(int v) : value(v) {} // 类型转换运算符 operator int() const { return value; } }; int main() { MyInteger obj(10); int num = obj; // 调用类型转换运算符将MyInteger对象转换为int类型 cout << num << endl; // 输出:10 return 0; }
- 构造函数和析构函数的调用顺序:
- 在创建对象时,构造函数的调用顺序是先调用基类的构造函数,然后才调用成员对象的构造函数,最后调用派生类的构造函数。
- 在销毁对象时,析构函数的调用顺序是与构造函数的调用顺序相反,先调用派生类的析构函数,然后调用成员对象的析构函数,最后调用基类的析构函数。
-
class Base { public: Base() { cout << "Base constructor" << endl; } ~Base() { cout << "Base destructor" << endl; } }; class Member { public: Member() { cout << "Member constructor" << endl; } ~Member() { cout << "Member destructor" << endl; } }; class Derived : public Base { private: Member member; public: Derived() { cout << "Derived constructor" << endl; } ~Derived() { cout << "Derived destructor" << endl; } }; int main() { Derived obj; // 创建一个派生类对象 return 0; }
- 输出:
-
Base constructor Member constructor Derived constructor Derived destructor Member destructor Base destructor
- 希望这些代码解释和说明能够进一步帮助你理解和掌握C++类的相关知识点。继续学习和实践类的概念和用法,将有助于提升你的C++编程技能和应用能力。如果你有任何问题,请随时向我提问。
c++类的知识总结
于 2023-08-09 14:37:07 首次发布