要声明类,可使用关键字 class,并在它后面依次包含类名,一组放在{}内的成员属性和成员函数, 以及结尾的分号。

  1. class Human
  2. {
  3. // Member attributes:
  4. string name;
  5. string dateOfBirth;
  6. string placeOfBirth;
  7. string gender;
  8. // Member functions:
  9. void Talk(string textToTalk);
  10. void IntroduceSelf();
  11. ...
  12. };

通过关键字 class,C++ 提供了一种功能强大的方式,让您能够创建自己的数据类型,并在其中封装属性和使用它们的函数

类相当于蓝图,仅声明类并不会对程序的执行产生影响。在程序执行阶段,对象是类的化身。要使用类的功能,通常需要创建其实例—对象,并通过对象访问成员方法和属性
Human firstMan; // firstMan: an object of class Human
就像可以为其他类型(如 int)动态分配内存一样,也可使用 new 为 Human 对象动态地分配内存

int* pointsToNum = new int; // an integer allocated dynamically
delete pointsToNum; // de-allocating memory when done using  

Human* firstWoman = new Human(); // dynamically allocated Human
delete firstWoman; // de-allocating memory

如果有一个指针 firstWoman,它指向 Human 类的一个实例,则可使用指针运算符(->)来访问成员,也可使用间接运算符(*)来获取对象,再使用句点运算符来访问成员:

Human* firstWoman = new Human();
(*firstWoman).IntroduceSelf();

firstWoman->dateOfBirth = "1970";
firstWoman->IntroduceSelf();
delete firstWoman;

如果对象是使用 new 在自由存储区中实例化的,或者有指向对象的指针,则可使用指针运算符(->) 来访问成员属性和方法:

#include <iostream>
#include <string>
using namespace std;

class Human
{
public:
    string name;
    int age;

    void introduce_self()
    {
        cout << "i am " + name << " and am " << age << " years old " << endl;
    }
};

int main(){
    Human *jiangyu = new Human();
    (*jiangyu).age = 28;
    (*jiangyu).name = "jiangyu";
    (*jiangyu).introduce_self();
    cout << endl;

    // 使用指针运算符访问成员属性和方法
    jiangyu->age = 128;
    jiangyu->name = "jiangyu_2";
    cout << "use ->" << endl;;
    jiangyu->introduce_self(); 
    delete jiangyu;
    return 0;
}

关键字public 和private

C++让您能够将类属性和方法声明为公有的,这意味着有了对象后就可获取它们;
也可将其声明 为私有的,这意味着只能在类的内部(或其友元)中访问。

#include <string>
#include <iostream>
using namespace std;

class Human
{
    private:
        int age;
        string your_name;
    public:
        int get_age()
        {
            return age;
        }

        void set_age(int human_age)
        {
            age = human_age;
        } 

        string get_name()
        {
            return your_name;
        }

        void set_name(string name)
        {
            your_name = name;
        }  
};

int main(){
    Human* lilei = new Human();
    int age_set = 20;
    string the_name = "jiangyu";
    (*lilei).set_age(age_set);
    (*lilei).set_name(the_name);
    cout << (*lilei).get_age() << endl;
    cout << (*lilei).get_name() << endl;
    delete lilei;
}

如果试图使用下述代码访问成员 age:

cout << (*lilei).age << endl; // compile error

报错 age 申明为private 非
image.png
通常是以编写 Human 类的程序员 认为的合适方式暴露 age 如 get_age()

构造函数

构造函数是一种特殊的函数(方法),在根据类创建对象时被调用。与函数一样,构造函数也可以 重载。

在类声明中实现(定义)构造函数

class Human {
    public:    Human()
    {         
       // constructor code here
    } 
}

在类声明外定义构造函数

class Human { 
    public:    Human(); // constructor declaration 
}; 

// constructor implementation (definition)
Human::Human() {
    // constructor code here 
}

没有默认构造函数,而在如果提供了重载的构造函数时,C++编译器不会为您生成默认构造函数。如果没有提供重载的构造函数且没有提供默认构造函数时,编译器会提供一个默认构造函数。

包含初始化列表的构造函数

#include <string>
#include <iostream>
using namespace std;

class Human
{
    private:
        int age;
        string your_name;
    public:
        Human(string name, int human_age)
            :your_name(name),age(human_age)
            {
                cout << "Constructed a human called " << your_name;
                cout << ", " << age << " years old" << endl;
            }
};

int main(){
    Human* lilei = new Human("hehe",13);
    delete lilei;
}

初始化列表由包含在括号中的参数声明后面的冒号标识,冒号后面列出了各个成员变量及其初始值。
初始值可以是参数(如 humansName),也可以是固定的值。使用特定参数调用基类的构造函数时, 初始化列表也很有用

接受带默认值的参数的默认构造函数

#include <string>
#include <iostream>
using namespace std;

class Human
{
    private:
        int age;
        string your_name;
    public:
        Human(string name = "hehe", int human_age = 13)
            :your_name(name),age(human_age)
            {
                cout << "Constructed a human called " << your_name;
                cout << ", " << age << " years old" << endl;
            }
};

int main(){
    Human* lilei = new Human();
    delete lilei;
}

将sizeof( )用于类

运算符 sizeof( )指出类声明中所有数据属性占用的总内存量,单位为字节

友元函数

不能从外部访问类的私有数据成员和方法,但这条规则不适用于友元类和友元函数。要声明友元 类或友元函数,可使用关键字 friend

#include <string>
#include <iostream>
using namespace std;

class Human
{
    private:
        friend void display_age(const Human& person);
        int age;
        string your_name;
    public:
        Human(string name = "hehe", int human_age = 13)
            :your_name(name),age(human_age)
            {
                cout << "Constructed a human called " << your_name;
                cout << ", " << age << " years old" << endl;
            }
};

void display_age(const Human& person)
{
    cout << person.age << endl;
}


int main(){
    Human* lilei = new Human();
    cout << "Accessing private member age via friend function: ";
    display_age(*lilei);
    delete lilei;
}

第 8 行的声明告诉编译器,函数 display_age( )是全局函数,还是 Human 类的友元,因此能够访问 Human 类的私有数据成员。

友元类

第 8行指出 Utility 类是 Human 类的友元,该声明让 Utility 类的所有方法都能访问 Human 类的私有数据成员和方法。

#include <string>
#include <iostream>
using namespace std;

class Human
{
    private:
        friend class Utility; //友元类
        int age;
        string your_name;
    public:
        Human(string name = "hehe", int human_age = 13)
            :your_name(name),age(human_age)
            {
                cout << "Constructed a human called " << your_name;
                cout << ", " << age << " years old" << endl;
            }
};

class Utility
{
    public:
        static void display_age(const Human& person)
        {
            cout << person.age <<endl;
        }
};

int main(){
    Human* lilei = new Human();
    cout << "Accessing private member age via friend class: ";
    Utility::display_age(*lilei);
    delete lilei;
}