C++ 基础代码模板和使用

作者: zcwfeng | 来源:发表于2021-03-20 06:45 被阅读0次

    C 语言不支持函数重载,C++才支持

    int add(int num1, int num2) {
        return num1 + num2;
    }
    
    int add(int num1, int num2, int num3) {
        return num1 + num2 + num3;
    }
    

    C++ 11 的 Auto

    类型推断,不指定变量类型,编译器根据初始值给定类型。
    auto n = 0;//int
    auto x = 0.0;//double
    auto y = 1.3e12L;//long double

    auto 处理复杂类型推断比较有明显作用,普通变量没必要。如在stl中的使用

    void testSTL(){
        std::vector<double> score;
        std::vector<double>::iterator pv = score.begin();
        auto pv2 = score.begin();
    }
    

    C++11 vector array

    int main(){
        double a1[4] = {1.2,2.4,3.6,4.8};
    
        vector<double> a2(4);
        a2[0]=1.2;
        a2[1]=2.4;
        a2[2]=3.6;
        a2[3]=4.8;
        array<double,4> a3={1.2,2.4,3.6,4.8};
        array<double,4> a4;
        a4 = a3;
    
        cout << "a1[2]: " << a1[2] << " at " << &a1[2] << endl;
        cout << "a2[2]: " << a2[2] << " at " << &a2[2] << endl;
        cout << "a3[2]: " << a3[2] << " at " << &a3[2] << endl;
        cout << "a4[2]: " << a4[2] << " at " << &a4[2] << endl;
    
        cout << "-------------" << endl;
        a1[-2] = 20.2;
        cout << "a1[-2]: " << a1[-2] << " at " << &a1[-2] << endl;
        cout << "a3[2]: " << a3[2] << " at " << &a3[2] << endl;
        cout << "a4[2]: " << a4[2] << " at " << &a4[2] << endl;
    
        cout << "a4[2]: " << a4.at(2) << " at " << &a4.at(2) << endl;
        cout << "a4[2]: " << *(a4.begin() + 2) << " at " << &(*(a4.begin() + 2)) << endl;
    
    //    a2.at(2);a2.begin();a2.end();
    
        return 0;
    }
    

    除了赋值,和使用,begin(),end(),at() 优化了数组越界的隐患。

    判断文件的结尾 EOF

    <iostream> 定义EOF 是文件的结尾

    字符函数库 <cctype>

    char ch = 'r';
    isalpha(ch) 是否为字母字符
    isdigit(ch) 是否是数字字符
    isspace(ch) 是否是空白换行等
    ispunct(ch) 是偶是标点符号
    

    引用变量

    int rat = 10;
    int &rat2 = rat;
    cout << "rat:" << rat << "--rat2:" << rat2 << endl;
    rat2 = 100;
    cout << "rat:" << rat << "--rat2:" << rat2 << endl;
    

    模板方法

    template <typename T>
    void Swap(T &a,T &b);
    int main() {
        int i = 10;
        int j=120;
        Swap(i,j);
        cout << "i:" << i << "--j:" << j << endl;
    
        return 0;
    }
    template <typename T>
    void Swap(T &a,T &b){
        T temp;
        temp = a;
        a = b;
        b = temp;
    }
    

    template <typename T>
    void Swap(T *a,T *b,n);

    定义操作数组模板

    命名空间

    namespace zcwfeng{
        class Top{
        }
    }
    

    using namespace zcwfeng;
    命名空间嵌套

    namespace zcwfeng2{
        namespace inner{
            namespace inner2{
                void out(){
                    
                }
            }
        }
    }
    using namespace zcwfeng2::inner::inner2;
    

    读入,写出 <iostream>

    cin.getline
    cin.clear
    cout<<endl;
    get() 面向行输入

    新增数据类型,和使用

    wchar_t title[] = L"wchar test";
        char16_t name[] = u"name test16";
        char32_t name2[] = U"name test32";
    

    公用体 Union

    union one4all{
        int intval;
        long longval;
        double doubleval;
    } pail;
    

    共用体的长度为其最大成员的长度。(pail有时可以是int,有时double,共用体只能存储一个值,因此必须有足够控件存储最大成员)
    当数据使用两种或者以上多种格式可以节省空间。如某些商品ID是整数,有一些是字符串。

    typedef struct widget{
        char brand[20];
        int type;
        union {
            long id_num;
            char id_char[20];
        };
    } prize;
    

    公用提是匿名的,因此id_num和id_char 视为两个成员,他们的地址相同。所以不需要中间标识符 ,我们自己负责那个成员是活动的。
    共用体常用(并非只能用于)节省内存。并非所有的四通都是现在这种大存储系统GB甚至TB级别。烤箱,mp3 等处理器内存节省就比较重要。公用体常用系统数据结构或硬件数据结构。

    常量指针,和指针常量

        int number = 9;
        int number2 = 8;
    
        // 常量指针
        const int * numberP1 = &number;
        // *numberP1 = 100; // 报错,不允许去修改【常量指针】存放地址所对应的值
         numberP1 = &number2; // OK,允许重新指向【常量指针】存放的地址
    
        //  指针常量
        int* const numberP2 = &number;
        *numberP2 = 100; // OK,允许去修改【指针常量】存放地址所对应的值
        // numberP2 = &number2; // 报错,不允许重新指向【指针常量】存放的地址
    
        // 常量指针常量
        const int * const numberP3 = &number;
        // *numberP3 = 100; // 报错,不允许去修改【常量指针常量】存放地址所对应的值
        // numberP3 = &number2; // 报错,不允许重新指向【常量指针常量】存放的地址
    

    浅拷贝和深拷贝

    默认拷贝函数,是浅拷贝,如果想要深拷贝需要手动处理

    如果有堆成员,必须实现深拷贝。

    -> 头文件
    #ifndef TEMPC_DEMO_H
    #define TEMPC_DEMO_H
    
    #include <iostream>
    #include <string>
    using namespace std;
    
    namespace PeopleN{
        class People{
        public:
    
            People(int age, string &name) : age(age), name(name) {
                this->name = name;
                this->age = age;
                this->nickName = static_cast<char *>(malloc(sizeof(char) * 10));
                cout << "两个参数构造函数" <<endl;
            }
    
    //        explicit People(int age) : age(age) {
    //            cout << "一个参数构造函数" <<endl;
    //        }
    
            explicit People(int age) : People(age,name="") {
                cout << "一个参数构造函数" <<endl;
            }
    
            virtual ~People() {
                cout << "析构!People"<<endl;
                //free 不能在c++使用,不会调用析构
                if(this->nickName){
                    free(nickName);
                    nickName = NULL;
                }
            }
    
    
            void test();
    
            int getAge() {
               return this->age;
            }
    
            const string &getName() {
                return this->name;
            }
    
    
    
            void setAge(int age) {
                this->age = age;
            }
    
            void setName(const string &name) {
                this->name = name;
            }
    
    
        private:
            int age;
            string name;
            char * nickName;
        };
    }
    #endif //TEMPC_DEMO_H
    

    实现

    People::People(int age, const string &name) : age(age), name(name) {
    
    }
    

    注意创建对象
    new---delete 成对的写

    auto people = new People(11);// 堆空间
    delete people;
    people = NULL;
    

    共有继承和私有继承

    private 继承在类内可以访问父类成员,外部不可以
    public 集成 在类外也可以访问父类成员
    父类可以给子类成员初始化

    多继承
    钻石问题,骡子问题

    1. 专门指定父类 :: 明确指定
    2. 重写父类 X不推荐
    3. virtual 声明父类方法

    C++ 可变参数

    #include <iostream>
    #include <stdarg.h> // 可变参数的支持
    using namespace std;
    
    // Java的可变参数: int ...
    // C++的可变参数写法:...
    // count的第一个用处:内部需要一个 存储地址用的参考值,如果没有第二个参数,内部他无法处理存放参数信息
    void sum(int count, ...) {
        va_list vp; // 可变参数的动作
    
        // 参数一:可变参数开始的动作vp
        // 参数二:内部需要一个 存储地址用的参考值,如果没有第二个参数,内部他无法处理存放参数信息
        va_start(vp, count);
    
        // 到这里后:vp就已经有丰富的信息
    
        // 取出可变参数的一个值
        int number  = va_arg(vp, int);
        cout << number << endl;
    
        // 取出可变参数的一个值
        number  = va_arg(vp, int);
        cout << number << endl;
    
        // 取出可变参数的一个值
        number  = va_arg(vp, int);
        cout << number << endl;
    
        // 越界 系统值 乱码
        // 取出可变参数的一个值 【娶不到后,会取系统值 乱码】
        number  = va_arg(vp, int);
        cout << number << endl;
    
        // 关闭阶段
        va_end(vp);
    }
    
    // 1.可变参数
    int main() {
        std::cout << "同学们大家好,我是Ferry" << std::endl;
    
        sum(546, 6,7,8);
    
        return 0;
    }
    
    

    循环取值和结束标记va_end

    void sum(int count, ...) {
        va_list vp;//可变参数
        va_start(vp, count);
    
        int i;
        for (i = 0; i <count; ++i) {
            int number = va_arg(vp, int);
            cout << number << endl;
        }
    
        va_end(vp);
    
    
    }
    
    int main() {
        sum(4, 6, 7, 8, 9);
        return 0;
    }
    

    static 关键字

    1. 可以直接通过类名::静态成员(字段/函数)
    2. 静态的函数只能取操作静态的属性和方法(同Java)
    3. 静态的属性必须要初始化,然后再实现(规则)
    /**
     * 静态的总结:
     * 1.可以直接通过类名::静态成员(字段/函数)
     * 2.静态的属性必须要初始化,然后再实现(规则)
     * 3.静态的函数只能取操作静态的属性和方法(Java)
     */
    
    #include <iostream>
    
    using namespace std;
    
    class Dog {
    public:
        char * info;
        int age;
    
        // 先声明
        static int id;
    
        static void update() {
            id += 100;
    
            // 报错:静态函数不能调用非静态函数(Java)
            // update2();
        }
    
        void update2() {
            id = 13;
        }
    };
    
    // 再实现
    int Dog::id = 9;
    
    int main() {
        Dog dog;
        dog.update2(); // 普通函数
        Dog::update(); // 静态函数
        dog.update(); // 对象名.静态函数(一般都是使用::调用静态成员,这种方式可以 知道就行)
    
        cout << Dog::id << endl;
        return 0;
    }
    

    方法+const

    void test const{
    }

    相当与常量指针常量,只读

    1. 常量引用不能改

    typedef struct {
        char name[10];
        int age;
    } Student;
    // 常量引用不能改
    void insertStudent(const Student & student){
    //    只读
    //    strcpy(student.name,"dfas");
    }
    int main(){
        Student student = {"张无忌",30};
        insertStudent(student);
        cout << student.name << ":"<<student.age<<;
    }
    

    2. 引用传递和指针的区别

    void numberChange(int *number1,int *number2){
        cout<< "numberChange"<< "num1-addr:"<< &number1 <<",num2-addr:"<< &number2<<endl;
    
        int temp = 0;
        temp = *number1;
        *number1 = *number2;
        *number2 = temp;
    }
    
    void numberChange2(int & number1,int & number2){
        cout<< "numberChange2" <<"num1-addr:"<< &number1 <<",num2-addr:"<< &number2<<endl;
    
        int temp = 0;
        temp = number1;
        number1 = number2;
        number2 = temp;
    }
    
    int main1(){
    
        int number1 = 10;
        int number2 = 20;
        cout<< "num1-addr:"<< &number1 <<",num2-addr:"<< &number2<<endl;
    
        numberChange(&number1,&number2);
    //    numberChange2(number1,number2);
        cout<< "num1:"<< number1 <<",num2:"<< number2<<endl;
        return 0;
    }
    

    3. 默认形参

    int add(bool isOK = 0){
        
    }
    

    4. 开源框架的一些写法

    这个样写是当前没想好,为了留下扩展使用

    void uploadToEngine(char * LogText,int ){
        
    }
    

    5. 释放对象

    new-delete

        Student student1;//栈空间
        Student * student = new Student();// 堆空间
        if(student){
            delete student;
            student = NULL;
        }
    

    当然和c语言一样也有

    6. 内联函数

    inline 加上了,并不是所有的编译器起作用。知识在一定成都上做了优化,内联函数不能递归,优化C语言宏定义不能作为值传递问题。

    7. 友元函数

    访问内部私有成员。

    8. 运算符重载 operator

    一般习惯性写在类内部,可以借用this指针,也可以直接获取内部私有成员
    参考系统写法,参数一般 【const 类 & 别名】

    1. 原因可以提高速度
    2. & 别名,只是创建副本引用
    3. const 限定不能随便调用函数更改

    9. 源码中属性初始化的方式。

    #include <iostream>
    using namespace std; // 已经声明了
    
    // 人类
    class Person {
    protected:
        // 注意:string 是 std 命名空间里面的成员,C++源码是这种写法std::string
        // string内部其实就是对 char*的封装
        string name;
        int age;
    public:
        Person(string name, int age) :name(name), age(age) {}
    };
    
    // 课程类
    class Course {
    private:
        string name;
    public:
        Course(string name) :name(name) {}
    };
    
    class Student : public Person {
    private:
        // 如果定义的是对象成员,必须这样初始化(构造函数的后面 : 对象成员(内容))  使用我们的第二种方式
        Course course; // 对象成员
    public:
        Student(string name, int age, Course course1, string courseNameInfo)
        :Person(name, age) // 既然继承了父类就必须给父类的构造函数初始化
    
        // ,
    
        // course(course1) // 第二种方式,编译阶段认可的 对象=对象   对象直接的赋值而已
    
         ,
    
         course(courseNameInfo) // 第三种方式, 对象(string内容)  直接初始化Course对象 --- 构造函数
    
        {
            // this->course = course1; // 第一种方式(对象=对象) 编译阶段不认可,无法监测到你是否真的给course对象成员初始化了
        }
    };
    
    int main() {
        Course c("C++");
        Student student("David", 30, c, "NDK内容真多");
    
        return 0;
    }
    

    相关文章

      网友评论

        本文标题:C++ 基础代码模板和使用

        本文链接:https://www.haomeiwen.com/subject/wfnbqltx.html