1 类和对象

1.1 声明类

和变量、函数一样,类也需要声明。要声明类,可使用关键字class,并在其后依次包含

  • 类名
  • 一组放在{}内的成员属性和成员函数
  • 结尾的分号

类声明将类本身及其属性告诉编译器。类声明本身并不能改变程序的行为,必须使用类,就像需要调用函数一样

class Human
{
  //成员属性
  string name;
  int age;
  
  //成员函数
  void setAge();
}

通过关键字class,C++提供一种功能强大的方式,让我们可以创建自己的数据类型,并在其中封装属性和使用属性的函数(方法),类的所有属性以及在其中声明的函数都是类的成员。

封装是指将数据及使用它们的函数进行逻辑编组,这是面向对象编程的重要特征

1.2 对象

仅声明类并不会对程序的执行产生影响。要使用类的功能,通常需要创建其实例--对象,并通过对象访问成员方法和属性

1.3 访问对象成员

1.3.1 句点运算符(.)

句点运算符既可以用来访问对象属性也可以访问对象方法。

Human firstMan;
firstMan.age=26;
firstMan.setAge();

1.3.2 指针运算符(->)

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

Human* firstWoman=new Human();
firstWoman->name="Alice";
firstWoman->setAge();
delete firstWoman;

2 类的保护属性:public和private

C++可以将成员声明为公有的,这在有了对象后即可获取它们;也可以声明为私有的,意味着只能在类的内部({}之间声明的成员)或其友元中访问。
假如有这样一个类:

class Human
{
private:
  //私有成员数据
  string name;
  int age;
  
public:
  int getAge(){
    return age;
  }
  void setAge(int humansAge){
    age=humansAge;
  }
}

假如有一个名为eve的Human实例:

Human eve;

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

cout<<eve.age;

将出现编译错误,要访问age的唯一途径就是通过Human类的公有方法getAge()。
保护属性可以让程序员决定要暴露哪些属性及如何暴露这些属性(比如在方法getAge()中,返回一个虚假的年龄)。

总之,C++让类的设计者能够控制类属性的访问和操作方式

3 构造函数

构造函数是一种特殊的函数,在根据类创建对象时被调用。

3.1 声明和实现构造函数

构造函数与类同名且没有返回值。构造函数既可以在类声明中实现(定义),也可以在类声明外实现。

类声明内实现:

class Human 
{
public:
  Human(){
    //构造函数代码
  }
};

类声明外实现:

class Human 
{
public:
  Human(); //构造函数声明
};

Human::Human(){
  //构造函数代码
}

::被称为作用域解析运算符。Human::age表示在Human类中声明的变量age,而::age表示全局作用域中的变量age

3.2 何时及如何使用构造函数

构造函数在创建对象时被调用,所以一般会在构造函数中初始化类成员变量。

可在不提供参数的情况下调用的构造函数称为默认构造函数。默认构造函数是可选的,如果声明类时没有提供默认构造函数,编译器将自动创建一个,这种构造函数会创建成员属性,但不会将POD类型的属性初始化为非零值。

3.3 重载构造函数

与函数一样,构造函数也可以重载,下面将创建一个将姓名作为参数的构造函数。

class Human 
{
public:
  Human(){
    //默认构造函数实现
  }

  Human(string humansName){
    //重载的构造函数实现
  }
};

当然也可以不实现默认构造函数,从而要求实例化对象时必须提供某些参数。没有默认构造函数并且类的设计者提供了重载的构造函数时,C++编译器将不会生成默认构造函数

3.4 带默认值的构造函数

构造函数也可以有带默认值的参数,用法和普通的带默认值函数一样。

class Human
{
private:
   int age;
   string name;

public:
//重载构造函数(没有默认构造函数)
   Human(string humansName, int humansAge = 25)
    {
      name=humansName;
      age=humansAge;
   }
};

实例化这个类时可以使用以下语法:

Human adam("Adam");
Human eve("eve",18);

默认构造函数是调用时可不提供参数的构造函数,而并不一定是不接受任何参数构造函数,下面的构造函数虽然有两个参数,但它们都有默认值,因此也是默认构造函数:

class Human
{
private:
   int age;
   string name;

public:
    //有两个参数的默认构造函数
   Human(string humansName=“Adam", int humansAge = 25)
    {
      name=humansName;
      age=humansAge;
   }
};

3.5 初始化列表

TODO...

4 析构函数

TODO...

5 复制构造函数

7 this指针

this指针是一个特殊的指针,它指向当前对象的实例,每一个对象都能通过this指针访问自己的地址。

this指针是一个隐藏的指针,可以在类的成员函数中使用,用来指向调用对象。当一个对象的成员函数被调用时,编译器会隐式地传递该对象的地址作为this指针。

友元函数没有this指针,因为友元函数不是类的成员,只有成员函数才有this指针

class Human
{
private:
  void Talk(string statement){
    cout<<statement;
  }
public:
  void introduceSelf(){
    Talk("bla bla");
  }
}

实际上,编译器在调用Talk时嵌入this指针,即Talk(this,"bla bla")

调用静态方法时,不会隐式传递this指针,因为静态函数不与类实例相关联,而由所有实例共享。要在静态函数中使用实例变量,应显示的声明一个形参,并将实参设置为this指针

posted on 2024-05-30 16:01  房东的猫hhhh  阅读(11)  评论(0编辑  收藏  举报