类与对象知识总结+封闭类+const+this指针 C++程序设计与算法笔记总结(三) 北京大学 郭炜(上)

简介: 类与对象知识总结+封闭类+const+this指针 C++程序设计与算法笔记总结(三) 北京大学 郭炜(上)

//C++程序到C程序的翻译

class CCar {
public:
int price;
void SetPrice(int p);
};
void CCar::SetPrice(int p) 
{ price = p; }
int main()
{
CCar car;
car.SetPrice(20000);
return 0;
}
struct CCar { 
int price; 
};
void SetPrice(struct CCar * this,
int p)
{ this->price = p; }
int main() {
struct CCar car;
SetPrice( & car, 
20000);
return 0;
}

this指针作用

其作用就是指向成员函数所作用的对象

非静态成员函数中可以直接使用this来代表指向该函数作用的对象的指针。

class Complex {
public:
double real, imag;
void Print() { cout << real << "," << imag ; }
Complex(double r,double i):real(r),imag(i) 
{ }
Complex AddOne() {
this->real ++; //等价于 real ++;
this->Print(); //等价于 Print
return * this;
} 
}; 
int main() {
Complex c1(1,1),c2(0,0);
c2 = c1.AddOne();
return 0;
} //输出 2,1
class A
{ 
int i;
public: 
void Hello() { cout << i << "hello" << endl; } 
};  void Hello(A * this ) { cout << this->i << "hello" 
<< endl; } 
//this若为NULL,则出错!!
int main() 
{ 
A * p = NULL;
p->Hello();  Hello(p);
} // 输出:hello

在C++中,this指针是一个特殊的指针,它指向当前对象的地址。它可以在类的成员函数中使用,用于访问调用该函数的对象的成员变量和成员函数。

当类的成员函数被调用时,编译器会隐式地传递一个this指针作为参数给该函数,以便让函数知道它是哪个对象的成员函数被调用了。通过this指针,我们可以在成员函数中访问对象的成员变量和其他成员函数。

举个例子,假设有一个名为"Person"的类,其中有一个成员变量name和一个成员函数printName(),那么在printName()函数中,可以使用this指针来访问name成员变量,如下所示:

class Person {
private:
    std::string name;
public:
    void setName(std::string n) {
        this->name = n;
    }
    void printName() {
        std::cout << "My name is: " << this->name << std::endl;
    }
};

在上面的例子中,this->name表示当前对象的name成员变量,this->name = n表示将传入的n赋值给当前对象的name成员变量。

需要注意的是,this指针只能在非静态成员函数中使用。静态成员函数没有this指针,因为它们不属于任何具体的对象。

总结一下,this指针在C++中用于访问当前对象的成员变量和成员函数,它是一个隐含传递给成员函数的指针。通过this指针,可以方便地操作和使用对象的成员。

在C++中,this指针是一个特殊的指针,它指向当前对象的地址。它可以在类的成员函数中使用,用于访问调用该函数的对象的成员变量和成员函数。

当类的成员函数被调用时,编译器会隐式地传递一个this指针作为参数给该函数,以便让函数知道它是哪个对象的成员函数被调用了。通过this指针,我们可以在成员函数中访问对象的成员变量和其他成员函数。

举个例子,假设有一个名为"Person"的类,其中有一个成员变量name和一个成员函数printName(),那么在printName()函数中,可以使用this指针来访问name成员变量,如下所示:

class Person {
private:
    std::string name;
public:
    void setName(std::string n) {
        this->name = n;
    }
    void printName() {
        std::cout << "My name is: " << this->name << std::endl;
    }
};

在上面的例子中,this->name表示当前对象的name成员变量,this->name = n表示将传入的n赋值给当前对象的name成员变量。

需要注意的是,this指针只能在非静态成员函数中使用。静态成员函数没有this指针,因为它们不属于任何具体的对象。

当涉及到多个对象之间的交互时,this指针也非常有用。通过使用this指针,我们可以将一个对象作为参数传递给另一个对象的成员函数,从而实现对象之间的通信。

举个例子,假设我们有两个类:Student和Teacher。在Teacher类中,我们定义了一个成员函数addStudent(),用于向Teacher对象中添加一个Student对象。代码如下所示:

class Student {
private:
    std::string name;
public:
    Student(std::string n) : name(n) {}
    std::string getName() {
        return name;
    }
};
class Teacher {
private:
    std::vector<Student> students;
public:
    void addStudent(Student& student) {
        students.push_back(student);
        std::cout << "Added student: " << student.getName() << std::endl;
    }
};

在上面的例子中,addStudent()函数接受一个Student对象的引用作为参数。通过使用this指针,我们可以在Teacher对象中调用该函数,并将当前Teacher对象作为参数传递给addStudent()函数,从而将自己添加到Teacher对象的students容器中。

使用示例如下:

int main() {
    Teacher teacher;
    Student student1("Alice");
    teacher.addStudent(student1);
    Student student2("Bob");
    teacher.addStudent(student2);
    return 0;
}

在上述示例中,我们创建了一个Teacher对象teacher,并创建了两个Student对象student1和student2。然后,我们通过调用teacher的addStudent()函数,将student1和student2添加到teacher对象的students容器中。

这个例子展示了如何使用this指针在对象之间传递信息,实现对象之间的交互。通过this指针,我们可以方便地操作其他对象的成员函数和成员变量。

this指针和静态成员函数

静态成员函数中不能使用 this 指针!

因为静态成员函数并不具体作用与某个对象!

因此,静态成员函数的真实的参数的个数,就是程序中写出的参数个数!

在C++中,this指针和静态成员函数之间有一些区别。

  1. 静态成员函数没有this指针:由于静态成员函数不属于任何特定的对象,它们没有this指针。因此,在静态成员函数中不能使用this指针来访问对象的成员变量或其他非静态成员函数。
  2. 静态成员函数可以直接访问静态成员:静态成员函数只能访问静态成员变量和其他静态成员函数。静态成员是与类关联而不是与对象关联的,所以无需实例化对象即可访问。这是因为静态成员在编译时已经被分配了内存空间。
  3. 非静态成员函数可以访问this指针:非静态成员函数可以使用this指针来访问调用该函数的对象的成员变量和其他非静态成员函数。this指针是一个隐式传递给非静态成员函数的指针,它指向当前对象的地址。

需要注意的是,静态成员函数可以通过类名直接调用,而非静态成员函数必须通过对象来调用。另外,静态成员函数在全局作用域中也是可见的,可以通过类名来访问,而非静态成员函数则需要通过对象或对象指针来访问。

举个例子,假设有一个名为"Math"的类,其中包含一个静态成员变量PI和一个静态成员函数add(),以及一个非静态成员变量num和一个非静态成员函数multiply()。代码如下所示:

class Math {
public:
    static const double PI;
    static int add(int a, int b) {
        return a + b;
    }
    int num;
    int multiply(int a, int b) {
        return a * b;
    }
};
const double Math::PI = 3.14159;

在上述示例中,静态成员变量PI可以直接通过类名访问,如Math::PI。静态成员函数add()也可以通过类名直接调用,如int sum = Math::add(2, 3)

而非静态成员变量num和非静态成员函数multiply()需要通过对象来访问,如:

Math math;
math.num = 10;
int product = math.multiply(4, 5);

总结一下,this指针只能在非静态成员函数中使用,用于访问当前对象的成员变量和其他非静态成员函数。静态成员函数没有this指针,只能访问静态成员变量和其他静态成员函数。静态成员通过类名直接访问,而非静态成员需要通过对象来访问。

在C++中,静态成员是属于类本身而不是类的实例的成员。静态成员在所有类的对象之间是共享的,它们被存储在静态数据区中,并且在程序运行期间只有一份副本。

静态成员可以是静态成员变量或静态成员函数。

  1. 静态成员变量:静态成员变量是与类关联而不是与类的对象关联的。它们由类的所有对象共享,无论创建多少个对象,静态成员变量都只有一个副本。静态成员变量通常用于表示与类相关的全局属性或计数器等。定义静态成员变量时,需要在声明前加上static关键字,并在类外部初始化。
class MyClass {
public:
    static int count;
};
int MyClass::count = 0; // 静态成员变量的初始化
int main() {
    MyClass::count++; // 访问静态成员变量使用类名和作用域解析运算符
    return 0;
}
  1. 静态成员函数:静态成员函数是与类关联而不是与类的对象关联的函数。它们不操作特定对象的成员变量,也没有this指针。静态成员函数可以直接通过类名调用,无需实例化对象。静态成员函数通常用于执行与类相关的一般操作,而不依赖于特定对象。
class MyClass {
public:
    static void printMessage() {
        std::cout << "This is a static member function." << std::endl;
    }
};
int main() {
    MyClass::printMessage(); // 调用静态成员函数使用类名和作用域解析运算符
    return 0;
}

需要注意的是,静态成员变量和静态成员函数都属于类本身,而不是类的对象。因此,在静态成员函数中不能直接访问非静态成员变量或非静态成员函数,只能访问其他静态成员。

总结一下,静态成员是属于类本身的成员,与类的对象无关。静态成员变量由类的所有对象共享,并且在程序运行期间只有一个副本。静态成员函数不依赖于特定对象,可以通过类名直接调用。静态成员通常用于表示与类相关的全局属性或执行与类相关的一般操作。

静态成员

普通成员变量每个对象有各自的一份,而静态成员变量一共就一份,为所有对象共享。

普通成员函数必须具体作用于某个对象,而静态成员函数并不具体作用于某个对象。

因此静态成员不需要通过对象就能访问。

在C++中,静态成员是属于类本身而不是类的实例的成员。静态成员在所有类的对象之间是共享的,它们被存储在静态数据区中,并且在程序运行期间只有一份副本。

静态成员可以是静态成员变量或静态成员函数。

  1. 静态成员变量:静态成员变量是与类关联而不是与类的对象关联的。它们由类的所有对象共享,无论创建多少个对象,静态成员变量都只有一个副本。静态成员变量通常用于表示与类相关的全局属性或计数器等。定义静态成员变量时,需要在声明前加上static关键字,并在类外部初始化。
class MyClass {
public:
    static int count;
};
int MyClass::count = 0; // 静态成员变量的初始化
int main() {
    MyClass::count++; // 访问静态成员变量使用类名和作用域解析运算符
    return 0;
}
  1. 静态成员函数:静态成员函数是与类关联而不是与类的对象关联的函数。它们不操作特定对象的成员变量,也没有this指针。静态成员函数可以直接通过类名调用,无需实例化对象。静态成员函数通常用于执行与类相关的一般操作,而不依赖于特定对象。
class MyClass {
public:
    static void printMessage() {
        std::cout << "This is a static member function." << std::endl;
    }
};
int main() {
    MyClass::printMessage(); // 调用静态成员函数使用类名和作用域解析运算符
    return 0;
}

需要注意的是,静态成员变量和静态成员函数都属于类本身,而不是类的对象。因此,在静态成员函数中不能直接访问非静态成员变量或非静态成员函数,只能访问其他静态成员。

总结一下,静态成员是属于类本身的成员,与类的对象无关。静态成员变量由类的所有对象共享,并且在程序运行期间只有一个副本。静态成员函数不依赖于特定对象,可以通过类名直接调用。静态成员通常用于表示与类相关的全局属性或执行与类相关的一般操作。

当使用静态成员时,有一些特性和注意事项需要了解:

  1. 静态成员变量的初始化:静态成员变量在类外部进行初始化,通常在源文件中进行。可以通过在类定义之外使用类名和作用域解析运算符来访问和初始化静态成员变量。
  2. 静态成员函数的调用:静态成员函数可以直接通过类名和作用域解析运算符来调用,无需实例化对象。它们不操作特定对象的成员变量,也没有this指针。因此,在静态成员函数内部不能直接访问非静态成员变量或非静态成员函数。
  3. 访问权限:静态成员可以具有公共、私有或受保护的访问权限修饰符,就像其他类成员一样。可以使用public、private或protected关键字来控制对静态成员的访问权限。
  4. 静态成员的作用域和生存周期:静态成员在类的整个生命周期都存在,并且在所有类的对象之间是共享的。静态成员的作用域限于其定义所在的类,可以通过类名和作用域解析运算符来访问。
  5. 静态成员的存储位置:静态成员变量在程序运行期间只有一个副本,它们被存储在静态数据区中。因此,无论创建多少个类的对象,静态成员变量始终保持相同的值。
  6. 静态成员和非静态成员之间的区别:静态成员属于类本身,而非静态成员属于类的对象。静态成员在所有对象之间共享,而非静态成员每个对象都有自己的副本。此外,静态成员函数没有this指针,无法访问非静态成员。

需要注意的是,静态成员的设计应该遵循一定的规则和原则。静态成员通常用于表示与类相关的全局属性或执行与类相关的一般操作,而不依赖于特定对象的状态。在使用静态成员时,应该明确其适用范围和目的,以保证代码的可读性和可维护性。

总结一下,静态成员是属于类本身的成员,与类的对象无关。静态成员变量在程序运行期间只有一个副本,静态成员函数可以直接通过类名调用。静态成员通常用于表示与类相关的全局属性或执行与类相关的一般操作。在使用静态成员时,应注意初始化、访问权限、作用域、生存周期等特性。

目录
相关文章
|
5月前
|
存储 安全 编译器
第二问:C++中const用法详解
`const` 是 C++ 中用于定义常量的关键字,主要作用是防止值被修改。它可以修饰变量、指针、函数参数、返回值、类成员等,确保数据的不可变性。`const` 的常见用法包括:
227 2
|
7月前
|
算法 API 计算机视觉
人脸识别笔记(一):通过yuface调包(参数量54K更快更小更准的算法) 来实现人脸识别
本文介绍了YuNet系列人脸检测算法的优化和使用,包括YuNet-s和YuNet-n,以及通过yuface库和onnx在不同场景下实现人脸检测的方法。
237 1
|
7月前
|
JSON 算法 数据可视化
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
这篇文章是关于如何通过算法接口返回的目标检测结果来计算性能指标的笔记。它涵盖了任务描述、指标分析(包括TP、FP、FN、TN、精准率和召回率),接口处理,数据集处理,以及如何使用实用工具进行文件操作和数据可视化。文章还提供了一些Python代码示例,用于处理图像文件、转换数据格式以及计算目标检测的性能指标。
137 0
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
|
7月前
|
数据可视化 搜索推荐 Python
Leecode 刷题笔记之可视化六大排序算法:冒泡、快速、归并、插入、选择、桶排序
这篇文章是关于LeetCode刷题笔记,主要介绍了六大排序算法(冒泡、快速、归并、插入、选择、桶排序)的Python实现及其可视化过程。
73 0
|
7月前
|
算法
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
70 0
|
11月前
|
C语言
指针进阶(C语言终)
指针进阶(C语言终)
|
6月前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
535 13
|
8月前
|
存储 人工智能 C语言
C语言程序设计核心详解 第八章 指针超详细讲解_指针变量_二维数组指针_指向字符串指针
本文详细讲解了C语言中的指针,包括指针变量的定义与引用、指向数组及字符串的指针变量等。首先介绍了指针变量的基本概念和定义格式,随后通过多个示例展示了如何使用指针变量来操作普通变量、数组和字符串。文章还深入探讨了指向函数的指针变量以及指针数组的概念,并解释了空指针的意义和使用场景。通过丰富的代码示例和图形化展示,帮助读者更好地理解和掌握C语言中的指针知识。
298 4
|
7月前
|
C语言
无头链表二级指针方式实现(C语言描述)
本文介绍了如何在C语言中使用二级指针实现无头链表,并提供了创建节点、插入、删除、查找、销毁链表等操作的函数实现,以及一个示例程序来演示这些操作。
88 0
|
10月前
|
编译器 C语言
【C语言初阶】指针篇—下
【C语言初阶】指针篇—下