C++ object-oriented programming

Object-Oriented Programming (OOP) is a programming paradigm, and its key basic concepts are classes (Class) and objects (Object). This programming paradigm is widely used in C++. In object-oriented thinking, we regard an object as the basic unit of a program, and an object contains data and functions for manipulating data.

1. The difference between object-oriented and process-oriented

Object-oriented is a programming idea that conforms to human thinking habits. There are various things in different forms in real life, and there are various connections between these things. Objects are used in the program to map real things, and the relationship between objects is used to describe the connection between things. This kind of thinking is object-oriented.

Process-oriented is to analyze the steps needed to solve the problem, and then use functions to realize these steps one by one, and call them one by one when using them.

Object-oriented is different from process-oriented. It divides the things that constitute the problem into multiple independent objects according to certain rules, and then solves the problem by calling the method of the object. Of course, an application will contain multiple objects, and the functions required by the application can be realized through the cooperation of multiple objects. In this way, when the function of the application changes, only individual objects need to be modified, making the code easier maintain.

2. The object-oriented programming idea in C++ has three characteristics:

1. Encapsulation : Encapsulation is an important feature in object-oriented programming. It allows us to bind data (variables) and methods (functions) to manipulate data to form a whole, which is what we call an object.

In C++, classes are the main tool for encapsulation. A class defines a new type that contains data members (member variables) and member functions. Outside the class, we cannot directly access the data members of the class, but only through member functions, which realizes the hiding and protection of data. This level of hiding and protection can be adjusted through access modifiers (private, protected, public).

class MyClass {
private:
    int myVariable;  // 私有数据成员,只能在类的成员函数中直接访问

public:
    void setMyVariable(int value) {  // 公有成员函数,可以从类的外部调用
        myVariable = value;
    }

    int getMyVariable() {  // 公有成员函数,可以从类的外部调用
        return myVariable;
    }
};

In this example, myVariableit is private and cannot be directly accessed from outside the class. We can only set and get the value of through the two public member functions setMyVariableof and .getMyVariablemyVariable

There are two main benefits of encapsulation:

① Improve security: By hiding the internal implementation details of the class, we can prevent external code from mishandling the internal data of the class.

② Improve maintainability: The external code interacts with the class through the public interface of the class, so that even if the internal implementation of the class changes, it will not affect the external code.

Therefore, encapsulation is a very important programming skill and the key to building robust and maintainable code.

2. Inheritance : In C++, inheritance is a mechanism for creating new classes (called derived classes), which inherit the attributes and behaviors of one or more existing classes (called base classes).

The main purpose of inheritance is for code reuse, but also for generalization and specialization of types. Generalization refers to extracting common parts from multiple classes to form a more general class. This process is also called extracting common base classes. Specialization is to add new attributes and behaviors on the basis of the base class to form a more specific class.

Take the following example as an example:

class Animal {
public:
    void eat() {
        cout << "I can eat!" << endl;
    }

    void sleep() {
        cout << "I can sleep!" << endl;
    }
};

class Dog : public Animal {
public:
    void bark() {
        cout << "I can bark! Woof!" << endl;
    }
};

In this example, Animalthe base class Dogis the derived class. DogWhen a class inherits from a class through public Animal, Dogthe class inherits Animalall public and protected members of the class. This means that Dogobjects of the class can eat ( ) and sleep ( ) like Animalobjects of the class , while the class also adds a new behavior: called ( ).eatsleepDogbark

It should be noted that there are three types of inheritance in C++: public inheritance (public), protected inheritance (protected) and private inheritance (private).

They mainly differ in the level of access to members of the base class in derived classes. Public inheritance is the most commonly used, and the public and protected members of the base class maintain the original access level in the derived class. Protected and private inheritance are relatively infrequently used, and they transform public and protected members of a base class into protected and private members, respectively, of a derived class.

In addition, C++ supports multiple inheritance, which means that a derived class can have multiple base classes. However, multiple inheritance may lead to some complicated problems (such as the diamond inheritance problem), so multiple inheritance should be used with caution when designing the inheritance relationship of classes.

3. Polymorphism : Polymorphism is an important concept in object-oriented programming, allowing us to deal with different types of objects in a unified way. In C++, polymorphism mainly manifests itself in two forms: compile-time polymorphism (static polymorphism) and run-time polymorphism (dynamic polymorphism).

①Compile- time polymorphism : mainly realized through function overloading and templates. Function overloading allows multiple functions to have the same function name but different parameter lists, and the compiler will decide which function to call at compile time based on the parameter list of the function. Templates allow us to define a schema so that a function or class can operate on multiple data types.

Function overloading means that in the same scope, there can be multiple functions with the same name, as long as their parameter lists are different. The compiler will determine which overloaded version of the function to call based on the type and number of incoming parameters. This kind of polymorphism occurs at the compilation stage, so it is called compile-time polymorphism.

For example:

void print(int a) {
    std::cout << "Printing int: " << a << std::endl;
}

void print(double a) {
    std::cout << "Printing double: " << a << std::endl;
}

void print(const std::string& str) {
    std::cout << "Printing string: " << str << std::endl;
}

int main() {
    int a = 5;
    double b = 3.14;
    std::string c = "Hello, World!";

    print(a); // 调用 print(int) 函数
    print(b); // 调用 print(double) 函数
    print(c); // 调用 print(const std::string&) 函数

    return 0;
}

Templates are a generic programming feature in C++ that allow us to define generic functions or classes without having to rewrite the same code for each data type. When the template is compiled, the corresponding concrete implementation will be generated according to the type actually used. This kind of polymorphism also occurs in the compilation phase, so it also belongs to compile-time polymorphism. Templates can be divided into function templates and class templates.

For example:

Function template :

template <typename T>
T add(T a, T b) {
    return a + b;
}

int main() {
    int a = 1, b = 2;
    double c = 1.5, d = 2.5;

    std::cout << add(a, b) << std::endl; // 调用 add<int> 函数
    std::cout << add(c, d) << std::endl; // 调用 add<double> 函数

    return 0;
}

class template :


template <typename T>
class MyContainer {
public:
    MyContainer(T item) : item_(item) {}

    T getItem() {
        return item_;
    }

private:
    T item_;
};

int main() {
    MyContainer<int> intContainer(42);
    MyContainer

②Runtime polymorphism : It is mainly realized through virtual functions (Virtual Functions) and abstract classes (Abstract Classes). By declaring a function in the base class as a virtual function, the derived class can override (override) this function to achieve different behavior from the base class. At runtime, the compiler will decide which version of the virtual function to call based on the actual type of the object, which is runtime polymorphism.

The following is an example of runtime polymorphism:

class Animal {
public:
    virtual void makeSound() {
        cout << "The animal makes a sound." << endl;
    }
};

class Dog : public Animal {
public:
    void makeSound() override {
        cout << "The dog barks." << endl;
    }
};

class Cat : public Animal {
public:
    void makeSound() override {
        cout << "The cat meows." << endl;
    }
};

In this example, Animala base class that defines a virtual function makeSound. Dogand Catare Animalderived classes of , which rewrite makeSoundthe function respectively. Now, we can use Animala pointer or reference of type to call makeSoundthe function, and at runtime, the corresponding function version will be called according to the actual object type.

Animal* animal1 = new Dog();
Animal* animal2 = new Cat();
animal1->makeSound();  // 输出 "The dog barks."
animal2->makeSound();  // 输出 "The cat meows."

This is a typical application of runtime polymorphism, which allows us to deal with different types of objects in a unified and flexible way.

Guess you like

Origin blog.csdn.net/2201_75772333/article/details/130474045