C++学习(三)

类与对象:

{

        类的构成:{

            把具有共同属性和行为的事物所构成的集合称为类

            类声明中包含数据和函数 即 数据成员和成员函数

            访问权限分为 public公有、private私有、protected保护 三种

            格式:{

                class 类名{

                    public:

                        公有数据成员;

                        公有成员函数;

                    protected:

                        保护数据成员;

                        保护成员函数;

                    private:

                        私有数据成员;

                        私有成员函数;

                };

            }                      

class Score{

                    public:

                        void setScore(int s);

                        void showScore();

                    private:

                        int mid_exam;

                        int fin_exam;

                };

   

           注释:一般的 一个类的数据成员声明为私有成员 成员函数声明为公有成员

                私有部分处于类的第一部分时 关键字private可以省略

                一个类中没有访问权限关键字 默认为私有

                不能在类声明中给数据成员赋初值

        }

        成员函数定义:{

            普通成员函数的定义 其形式如下:

                返回值类型 类名::成员函数名(参数表) { 函数体 }

            在类的声明中 只给出成员函数的原型 定义在类的外部                 

eg: { 

        class Score{

            public:

                void setScore(int mid, int fin);

                void showScore();

            private:

                int mid_exam;

                int fin_exam;
        };

        void Score::setScore(int mid, int fin)

        {

                 mid_exam = mid;

                 fin_exam = fin;

         }

        void Score::showScore(void)

        {

                 cout << "mid_exam = " << mid_exam << endl;

                 cout << "fin_exam = " << fin_exam << endl;

        }

        int main()

        {

                 Score s1;

                 s1.setScore(80, 90);

                 s1.showScore();

                return 0;

        }

}

            内联成员函数定义:{

                隐式声明 将成员函数直接定义在类内部

                显示声明 在类声明中只给函数原型 定义在类外部

            }

            eg:{

                // 隐式内联成员函数

                class Score{

                    public:

                        int add(int a, int b)

                        {

                            .....

                        }

                    private:

                        ....

                };

                // 显示内联成员函数

                class Student{

                    public:

                        inline int add(int a, int b);

                    private:

                        ...

                };

                inline int Student::add(int a, int b)

                {

                    ...

                }

                注释 :用inline定义的内联函数 声明和定义须在同一文件中 否则编译器无法区分

            }

        }

        对象的定义及使用:{

            声明类的同时 直接定义对象

                eg:{

                    class Score{

                        public:

                            void setScore(int mid, int fin);

                            void showScore();

                        private:

                            int mid_exam;

                            int fin_exam;

                    }op1, op2;      // 定义两个对象op1和op2

                }

            声明类后 定义对象

                eg:{

                    Score s1, s2;   // 定义两个对象s1和s2

                }

            对象中成员的访问 形式如下

                对象名.数据成员名 或 对象名.成员函数名(参数列表)

                eg:{

                    op1.setScore(80, 90);

                    op1.showScore();

                }

            注释:

                类的内部所有成员之间都可通过成员函数直接访问 类的外部 不能访问对象的私有成员

                定义对象时 若是指向此对象的指针变量 则用'->'操作符访问成员对象

                eg:{

                    Score *p ;

                    p->setScore(80, 90);

                }

            类的作用域及类成员的访问属性:{

                私有成员只能被类中成员函数访问 不能在类外部通过类的对象进行访问

                一般来说 公有成员是类的对外接口 私有成员是类的内部数据和内部实现

                类的访问级别优点 信息隐藏 数据保护

            }

        }

        构造函数与析构函数:{

            构造函数:{

                构造函数是一种特殊的成员函数 主要用于为对象分配空间 进行初始化

                构造函数的名称与类名相同 无返回值 参数类型任意(可不带参数)

                构造函数的调用方式 无需显示调用 系统在创建对象时自动调用 且只执行一次

                eg:{

                    class Score{

                        public:

                            Score(int mid, int fin);   // 构造函数

                            void setScore(int mid, int fin);

                            void showScore();

                        private:

                            int mid_exam;

                            int fin_exam;

                    };

                    Score::Score(int mid, int fin)

                    {

                        mid_exam = mid;

                        fin_exam = fin;

                    }

                }

                建立对象时 采用构造函数给数据成员赋值 形式如下

                类名 对象名(参数表)

                    Score s1(80, 90);

                    s1.showScore();

                类名 *指针变量名 = new 类名(参数表)

                    Score *p = new Score(80, 90);  // 同Score *p; p = new Score(80, 90);

                    p->showScore();

            }

            成员初始化列表:{

                数据成员的初始化一般在构造函数中进行 也可使用成员初始化列表实现数据成员初始化

                格式:

                    类名::构造函数名(参数表): 数据成员名1(初值1), 数据成员名2(初值2), ...

                    {

                        // 构造函数体

                    }

eg:{

        class Animal{

                   private:

                            int age;

                            int& a_age;

                            const double pi;

                    public:

                             Animal(int v):age(v), a_age(age), pi(3.14)

                            {

                            }

                            void show()

                            {

                                    cout << "age = " << age << "a_age =" << a_age << "pi = " << pi << endl;

                             }

          };

}

                    类成员初始化顺序按照声明顺序进行

            }

            带默认参数的构造函数:{

                eg:{

                        class Score{

                            public:

                                Score(int mid = 0, int fin = 0);

                                ...

                            private:

                                int mid_exam;

                                int fin_exam;

                        };

                        Score::Score(int mid, int fin):mid_exam(mid), fin_exam(fin)

                        {

                            cout << "构造函数使用中...." << endl;

                        }

                }

            }

            析构函数:{

                析构函数也是一种特殊的成员函数 执行与构造函数相反的操作

                通常用于撤销对象时一些清理任务 如释放分配给对象的内存空间

                析构函数特点

                            析构函数与构造函数名相同 前面一个'~'

                            析构函数无参数 无返回值 不能重载

                            撤销对象时 系统自动调用析构函数

                eg:{

                    class Score{

                        public:

                            Score(int mid, int fin); // 构造函数

                            ~Score();   // 析构函数

                        private:

                            int mid_exam;

                            int fin_exam;

                    };

                    Score::Score(int mid, int fin) : mid_exam(mid), fin_exam(fin)

                    {

                        cout << "构造函数使用中...." << endl;

                    }

                    Score::~Score()

                    {

                        cout << "析构函数使用中...." << endl;

                    }

                }

            }

            默认的构造函数和析构函数:{

                若未定义构造函数 则系统自动生成一个默认的构造函数

                对未定义构造函数的类 其公有数据成员可用初始值列表进行初始化

                eg:{

                   

                   class Stu{

                        public:

                            char name[10];

                            int no;

                    };

                    Stu s1 = {"张三", 1001};

                    cout << s1.name << " " << s1.no << endl;

                }

                若未定义析构函数 则系统自动生成默认析构函数

            }

            构造函数的重载:{

                class Stu{

                    public:

                        Stu(int n, char *name);

                        Stu();

                        ...

                    private:

                        ...

                };

                注释:无参构造函数和带默认参数的构造函数重载时 可能产生二义性

            }

#include<iostream>

#include <cstring>

using namespace std;

class Student{
private:
    char *stu_name;
    char *stu_no;
    float stu_score;
public:
    Student(char *name1, char *no1, float score1);
    ~Student();
    void modify(float score2);
    void stuShow();

};

Student::Student(char *name1, char *no1, float score1)
{
    stu_name = new char[strlen(name1)+1];
    strcpy(stu_name, name1);
    stu_no = new char[strlen(no1)+1];
    strcpy(stu_no, no1);
    stu_score = score1;
}

Student::~Student()
{
    delete []stu_name;
    delete []stu_no;
}

void Student::modify(float score2)
{
    stu_score = score2;
}

void Student::stuShow()
{
    cout << "The name of student is: " << stu_name << endl;
    cout << "The number of student is: " << stu_no << endl;
    cout << "The score of student is: " << stu_score << endl;
}


int main()
{
    Student stu1("Tom", "2019001", 95.5);
    // stu1.stuShow();
    stu1.modify(100);
    stu1.stuShow();

    return 0;
}

  拷贝构造函数:{

                拷贝构造函数是一种特殊的构造函数 其形参是本类对象的引用 用于将一个已有的对象去初始化另一个新的对象

                每个类必须有一个拷贝构造函数 若没有定义 则系统自动生成一个默认的拷贝构造函数 用于复制与数据成员值完全相同的新对象

                格式:

                    类名::类名(const 类名 &对象名)

                    {

                        // 拷贝构造函数体

                    }

                调用拷贝构造的形式如下:

                    类名 对象2(对象1);

                    类名 对象2 = 对象1;

                eg:{

                    class Score{

                        public:

                            Score(int mid, int fin);           // 构造函数

                            Score();

                            Score(const Score &s);           // 拷贝构造函数

                            ~Score();           // 析构函数

                            ...

                        private:

                            int mid_exam;

                            ...

                    };

                    Score::Score(int mid, int fin)

                    {

                        mid_exam = mid;

                        ...

                    }

                    Score::Score(const Score &s)

                    {

                        mid_exam = s.mid_exam;

                        ...

                    }

                    int main()

                    {

                        Score s1(80, 90);

                        Score s2(s1);       // 调用拷贝构造函数

                        Score s3 = sc2;    // 调用拷贝构造函数

                        return 0;

                    }

                }

            }

  深拷贝与浅拷贝:{

                浅拷贝 由默认的拷贝构造函数所实现的数据成员逐一赋值

                若类中含有指针类型数据 则浅拷贝的两个对象将指向同一块内存 那么系统调用析构函数后将导致同一空间多次释放而产生错误

            }

        }

  自引用指针'this': {

            this 指针保存当前对象的地址

            eg:{

                void Sample::copy(Sample &s)

                {

                    if(this == &s)

                        return;

                    *this = s;

                }

            }

        }

  对象数组与对象指针:{

            对象数组:{

                类名 数组名(元素个数);

                eg:{

                    用只有一个参数的构造函数给对象数组赋值

                    Exam ob[4] = {89, 90, 91, 92};

                    用不带参数和一个带参数的构造函数给对象数组赋值

                    Exam ob[4] = {91, 92};

                    用带多个参数的构造函数给对象数组赋值

                    Score ob[3] = {Score{80, 90}, Score{70, 80}, Score{60, 70}};

                }

            }

            对象指针:{

                对象指针就是用于存放对象地址的变量 其形式如下:

                    类名 *对象指针变量名;

                    eg:{

                        Score score;

                        Score *p = &score;

                        p->成员函数名();

                    }

            }

            用对象指针访问对象数组

        eg:{

                Score score[2];

                score[0].setScore(80, 90);

                score[1].setScore(70, 80);

                Score *p ;

                P = score;

                p->showScore();

                p++;

                p->showScore();

                Score *p1 = &score[1];         // 指向score[1]的指针

            }

        }

#include <iostream>

#include <cstring>

using namespace std;

class Stu{
    public:
        Stu(char *stu_name, int stu_age);
        ~Stu();
        Stu(const Stu& s);
        void show_stu(void);
    private:
        char *name;
        int age;
};

Stu::Stu(char *stu_name, int stu_age)
{
    name = new char[strlen(stu_name)+1];
    strcpy(name, stu_name);
    age = stu_age;
}

Stu::~Stu()
{
    delete []name;
}

Stu::Stu(const Stu& s)
{
    name = new char[strlen(s.name)+1];
    strcpy(name, s.name);
    age = s.age;
}

void Stu::show_stu(void)
{
    cout << "The name of student is: " << name << endl;
    cout << "The age of student is: " << age << endl;
}

int main()
{
    Stu s1("Tom", 18);
    // s1.show_stu();
    Stu s2(s1);
    s2.show_stu();
    // s2.age = 19;         // error: age is a private member of class Stu

    return 0;
}

  string 类{

            头文件 #include <string>

            常用string类运算符 : = + += == != > >= < <= [](下标) >> <<

eg:{

        string s1;              // 默认初始化,s1为空字符串

        string s2(s1);          // s2是s1的副本,等价于 s2 = s1

        string s3("value");     // s3是字面值"value"的副本(除字面值最后那个空字符外),等价于 s3 = "value"

        string s4(n, 'c');      // 把s4初始化为连续n个字符c组成的字符串 等价于string s4 = string(n, 'c')

}

            注释:使用等号(=)初始化一个变量, 则是拷贝初始化, 反之为直接初始化

            'getline' 读取一行:

eg:{

        string s;

        getline(cin, s);           // 从标准输入读取一行到字符串s中 直到遇到换行符为止

}

            'empty' 判断字符串是否为空:

eg:{

        string s1;

        if(s1.empty())          // 判断是否为空行

        cout << "s1 is empty" << endl;

}

            'size' 获取字符串长度:

eg:{

        string s2("I am still stuck in the rain");

        auto len = s2.size();   // 获取字符串长度  len 的类型是 string::size_type

}

                注释: 一条表达式中若有了size()函数 则不需要使用int 避免混用int和unsigned

            'ispunct' 判断是否为标点符号:

eg:{

        string s3("my hair is still wet");

        if(ispunct(s3[0]))

        cout << "s3[0] is a punctuation" << endl;

}

            'toupper' 转换为大写:

eg:{

        string s4("Under mount fuji");

        toupper(s4[6]);   // 将s4[6]转换为大写

        toupper(s4);      // 将字符串s4转换为大写

}

            字符串string与字面值 (字符串字面值与string是不同类型)

eg:{

        string s1 = "your trace are still with me";

        string s2 = "like dust without measure"

        string s3 = s1 + s2;           // 字符串相加

        string s4 = s1 + "like dust without measure"         // 字符串字面值相加

        string s5 = "like dust" + "without measure"         // error: 字面值不可相加

}

}

#include <iostream>

#include <string>
using namespace std;

int main()
{
    string str1 = "hello myself";
    string str2("my name is zozo");
    string str3 = str1 + " " + str2;
    cout << " " << str3 << endl;
    str2 += str2;
    str3 += " off";
    cout << " " << str2 << endl;
    cout << " " << str3 << endl;

    cout << "str == str1 ? " << (str1 == str2) << endl;
    cout << "str!= str1 ? " << (str1!= str2) << endl;
    cout << "str < str1  ? " << (str1 < str2) << endl;
    cout << "str > str1  ? " << (str1 > str2) << endl;

    return 0;
}

        向函数传递对象:{

            对象作为函数参数 (不影响实参本身)

            对象指针作为函数参数 (将影响实参对象的值)

            对象引用作为函数参数 (普遍应用)

        }

#include <iostream>

using namespace std;

class Point{
    public:
        int x;
        int y;
        Point(int x1, int y1):x(x1), y(y1)
        {}
        int distance()
        {
            return x*x + y*y;
        }
};

void print_distance(Point p1)   // 使用对象作为函数参数
{
    p1.x += 1;
    p1.y -= 1;
}

void change_point1(Point *p)     // 使用对象指针作为函数参数
{
    p->x += 1;
    p->y -= 1;
}

void change_point(Point& p)     // 使用引用作为函数参数
{
    p.x += 1;
    p.y -= 1;
}

int main()
{
    Point point[3] = {Point(1, 2), Point(3, 4), Point(5, 6)};
    Point *p = point;
    print_distance(*p);
    cout << "The distance of point1 is: " << p[0].distance() << endl;
    p++;
    change_point1(p);
    cout << "The distance of point2 is: " << p->distance() << endl;
    change_point(point[2]);
    cout << "The distance of point3 is: " << point[2].distance() << endl;

    return 0;
}

        静态成员:{         关键字 'static'

            静态数据成员:{

                无论建立多少类的对象 都仅有一个静态数据成员的拷贝 所有对象共享同一份静态数据

                需在类外且定义对象前 单独初始化

                形式如下 : static 数据类型 数据成员名;

                访问格式:

                          类名::静态数据成员名;

                          对象名.静态数据成员名;

                          对象指针->静态数据成员名;

            }

            静态成员函数:{

                静态成员函数属于整个类 是该类所有对象共享的成员函数

                静态成员函数的作用: 处理静态数据成员

                静态成员函数限定为内部连接 私有静态成员函数不被类外部函数和对象访问

                形式如下: static 返回值类型 静态成员函数名(参数表);

                访问格式:

                        类名::静态成员函数名(参数表);   //(常用形式)

                         对象名.静态成员函数名(参数表);

                         对象指针->静态成员函数名(参数表);

            }

        }

#include <iostream>

using namespace std;

class Score{
    private:
        int mid_exam;
        int fin_exam;
        static int count;
        static float sum;
        static float ave;   // 静态成员变量
    public:
        Score(int m, int f);
        ~Score();
        static void show_count_sum_ave();   // 静态成员函数
};

Score::Score(int m, int f)
{
    mid_exam = m;
    fin_exam = f;
    count++;
    sum += fin_exam;
    ave = sum / count;
}

Score::~Score()
{

}

/* 静态成员初始化 */
int Score::count = 0;
float Score::sum = 0;
float Score::ave = 0;

void Score::show_count_sum_ave()
{
    cout << "The count of scores is: " << count << endl;
    cout << "The sum of scores is: " << sum << endl;
    cout << "The average of scores is: " << ave << endl;
}

int main()
{
    Score sco[3] = {Score(80, 90), Score(70, 80), Score(90, 95)};
    sco[1].show_count_sum_ave();
    Score::show_count_sum_ave();

    return 0;
}

        友元:{       关键字 'friend'

                包括友元函数和友元类

                用于对私有或保护成员进行访问

            友元函数:{

                可以是不属于任何类的非成员函数 也可以是另一个类的成员函数 可访问该类的所有成员

               

将非成员函数声明为友元函数 

eg:{

        class A{

                public:

                        A(int x);

                        friend int getA(A &a);

                        ...

                private:

                       int Bb;

         };

        int getA(A &a)

        {

                return a.Bb;

        }

}

}            

友元类:{

                将一个类声明为另一个类的友元

                class Y{

                    ...

                };

                class X{

                    friend Y;           // 声明Y为X的友元类

                };

            }

            友元关系不具备'交换性'和'传递性'

        }

        类的组合:{

            在一个类中内嵌另一个类的对象作为数据成员 称为类的组合 该内嵌对象称为对象成员 又称子对象

            class A{

                ...

            };

            class B{

                A a;           // 内嵌A对象作为数据成员

                ...

            };

        }

        共享数据的保护:{

            常引用   const 类型& 引用名

            eg:{

                int a = 5;

                const int &b = a;   // 此时b的值就不能被修改了

                int add(const int &m,, const int &n)

                {

                    return m+n;

                }

                //此函数中m和n都是常引用 不能被修改

            }

        常对象:{

                    类名 const 对象名(参数表);

                    const Date date(2021,1,1);

        常对象成员:{

                    常数据成员 使用const修饰

                    若一个类中声明了常数据成员 则构造函数只能通过成员初始化列表来初始化该常数据成员 其他函数不能改变该值

                }

        常成员函数:{

                    形式如下:  类名 函数名(参数表) const;

eg:{

        calss Date{

                public:

                        Date(int year, int month, int day);

                        int getYear() const;   // 常成员函数

                        ...

                private:

                        int Dyear;

                        int Dmonth;

                        int Dday;

        };

        Date::Date(int year, int month, int day) : Dyear(year), Dmonth(month), Dday(day)

        { }

        int Date::getYear() const  // 常成员函数

        {

                ...

        }

        

const可被用于对重载函数区分

}

  }

                注释:常成员函数可以访问常数据成员 也可访问普通数据成员

                      常对象只能调用它的常成员函数 不能调用它的普通成员函数 常成员函数是常对象唯一对外的接口

            }

        }

   }

#include <iostream>

#include <string>

using namespace std;

class Score;   // 提前声明Score类以便引用

class Student{
    private:
        string name;
        int number;
    public:
        Student(string na, int num)
        {
            name = na;
            number = num;
        }
        friend void show_score(Score &sc, Student &st);   // 声明show_score为友元函数
};

class Score{
    private:
        int mid_exam;
        int fin_exam;
    public:
        Score(int m, int f)
        {
            mid_exam = m;
            fin_exam = f;
        }
        friend void show_score(Score &sc, Student &st);   // 声明show_score为友元函数
};

void show_score(Score &sc, Student &st)
{
    cout << "The name of student is: " << st.name << "student number is: " << st.number << endl;
    cout << "The mid_exam score is: " << sc.mid_exam << " fin_exam score is: " << sc.fin_exam << endl;
}

int main()
{
    Score sco1(80, 90);
    Student st("Tom", 20101);
    show_score(sco1, st);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值