飞道的博客

C++ 指向类的指针 指向类的对象

682人阅读  评论(0)

一个指向 C++ 类的指针与指向结构的指针类似,
访问指向类的指针的成员,需要使用成员访问运算符 ->,就像访问指向结构的指针一样。
与所有的指针一样,您必须在使用指针之前,对指针进行初始化。

C++的精髓之一就是多态性,只有指针或者引用可以达到多态。对象不行

用指针:
第一实现多态。
第二在函数调用,传指针参数。不管你的对象或结构参数多么庞大,你用指针,传过去的就是4个字节。如果用对象,参数传递占用的资源就太大了

类的指针:他是一个内存地址值,他指向内存中存放的类对象(包括一些成员变量所赋的值).
对象:他是利用类的构造函数在内存中分配一块内存(包括一些成员变量所赋的值).
在应用时:
1.引用成员: 对象用" . "操作符; 指针用" -> "操作符.
2.生命期: 若是成员变量,则是类的析构函数来释放空间;若是函数中的临时变量,则作用域是该函数体内;而指针,则需利用delete 在相应的地方释放分配的内存块.
注意:用new ,一定要delete

类的对象:用的是内存栈,是个局部的临时变量.
类的指针:用的是内存堆,是个永久变量,除非你释放它.

C++类的对象和类的指针的区别

#include <iostream> 
#include <string> 
using namespace std; 
class Student 
{ 
public: 
static int number;  
string name; 

public: 
Student() { } 
void set(string str) 
{ 
name = str; 
number++;    // 调用静态数据成员 
} 

void print()  // 态成员函数 print() 
{ 
std::cout < < name < <" : The number of the students is " < < number < < " numbers." < < std::endl; // 调用静态数据成员 
} 
}; 

int Student::number = 0;  // 静态数据成员初始化 

int main(int argc, char** argv) 
{ 
Student* s1; 
s1 = new Student(); 
s1->set("111"); 

Student s2; 
s2.set("222"); 

s1->print(); 
s2.print(); 

return 0; 
}

对于类student ,定义了一个对象和一个指针。

类的指针:是内存地址值,指向内存中存放的类对象
对象:利用类的构造函数在内存中分配一块内存
在应用时:
1.引用成员: 对象用" . “操作符; 指针用” -> "操作符.
2.生命期: 若是成员变量,则是类的析构函数来释放空间;若是函数中的临时变量,则作用域是该函数体内;而指针,则需利用delete 在相应的地方释放分配的内存块.
注意:用new ,一定要delete…

类的对象:用的是内存栈,是个局部的临时变量.
类的指针:用的是内存堆,是个永久变量,除非你释放它.

堆栈中到底存储数据包括:函数的参数,函数的局部变量等,这些数据是按照一定的顺序组织在一起的,我们称之为一个堆栈帧(Stack Frame)。一个堆栈帧对应一次函数的调用。在函数开始时,对应的堆栈帧已经完整地建立了(所有的局部变量在函数帧建立时就已经分配好空间了,而不是随着函数的执行而不断创建和销毁的);在函数退出时,整个函数帧将被销毁。

在文中,我们把函数的调用者称为Caller(调用者),被调用的函数称为Callee(被调用者)。之所以引入这个概念,是因为一个函数帧的建立和清理,有些工作是由Caller完成的,有些则是由Callee完成的。

堆栈是用来支持函数的调用和执行的

当类是有虚函数的基类,Func是它的一个虚函数,则调用Func时:
类的对象:调用的是它自己的Func;
类的指针:调用的是分配给它空间时那种类的Func;

对于一个类的对象和这个类的指针(用new运算符分配内存)在应用时有何区别
1.类和对象是两回事,对象是类的实例;
2.对象是在栈中分配的,使用new生成的对象是在堆中分配的;
3.要发挥虚函数的强大作用,必须使用指针来访问对象.

指针可以实现多态,直接用对象不行
执行定义对象,在栈空间
new处的在堆

注意名字的类型.
一个是Student
一个是Student*
Student是直接访问一个对象
Student*是间接访问一个对象,因为通过了一个指针作媒介.
类型决定了你能做什么.

其实作用基本一样 都是为了调用类的成员变量 和成员函数用的
当你希望明确使用这个类的时候,最好使用对象,如果你希望使用C++中的动态绑定,则最好使用指针或者引用
指针和引用用起来更灵活,容易实现多态等

类的指针:他是一个内存地址值,他指向内存中存放的类对象(包括一些成员变量所赋的值).
对象,他是利用类的构造函数在内存中分配一块内存(包括一些成员变量所赋的值).

1.在类的声明尚未完成的情况下,可以声明指向该类的指针,但是不可声明该类的对象…
2.父类的指针可以指向子类的对象…

定义对象实例时,分配了内存。指针变量则未分配类对象所需内存
指针变量是间接访问,但可实现多态(通过父类指针可调用子类对象),并且没有调用构造函数。
直接声明可直接访问,但不能实现多态,声明即调用了构造函数(已分配了内存)。
至于那个效率高要看程序调用过程而定。

C++的精髓之一就是多态性,只有指针或者引用可以达到多态。对象不行

用指针:
第一实现多态。
第二,在函数调用,传指针参数。不管你的对象或结构参数多么庞大,你用指针,传过去的就是4个字节。如果用对象,参数传递占用的资源就太大了

没有例子不说话

指向地址的指针


指针本身的大小


指向数组的指针


指针数组

指向指针数组的指针

多维指针数组

函数参数中使用指针

#include <stdio.h>

int myswap(int *a, int *b){
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main() {
    int x = 50;
    int y = 30;
    myswap(&x, &y);
    printf("x:%d  y:%d\n", x, y);
    return 0;
}

// x:30  y:50

// 这个程序看似简单, 但是却应用到了而很多高级的算法,
// 指针 引用 当初不理解,现在终于理解了!

数组指针传址实现数组求和

#include <iostream>
using namespace std;

int mysum(int length, int *data){
    int myresult = 0;
    int i;
    for(i = 0; i < length; i++)
    {
        myresult += *(data + i);
        cout << *(data + i) << endl;
        cout << data + i << endl;
    }
    return myresult;
}

int main() {
    int x[5] = {1, 2, 3, 4, 5};
    int restult;
    restult = mysum(5, x);
    cout << x << endl;
    printf("%d\n", restult);
    return 0;
}
// 输出结果:
//0x7ffecd866750
//1
//0x7ffecd866754
//2
//0x7ffecd866758
//3
//0x7ffecd86675c
//4
//0x7ffecd866760
//5
//0x7ffecd866750
//15

函数指针

#include <iostream>
using namespace std;

int add(int a, int b);

int main(int argc, char **argv)
{
    int (*myfunc)(int a, int b);
    myfunc = add;
    int x = myfunc(12, 36);
    cout << x << endl;
    return 0;
}

int add(int a, int b)
{
    return a + b;
}

// 48

模仿C++ 类别

#include <iostream>
using namespace std;

struct mynum{
    int a;
    int b;
    int result;
    void(*mod_add)(int a, int b, int *result);
};

void madd(int a, int b, int *result){
    (*result)=(a + b) % 13;
}

int main(void){
    struct mynum mnum;
    mnum.a = 12;
    mnum.b = 26;
    mnum.mod_add=madd;
    mnum.mod_add(mnum.a, mnum.b, &mnum.result);
    cout << mnum.result << endl;
    return 0;
}

// 12

函数指针数组

#include <stdio.h>
#include <stdlib.h>

int add(int a, int b){
    return a + b;
}

int sub(int a, int b){
    return a - b;
}

int main (int argc, char **argv) {
    int (*operate_func[])(int, int) ={add, sub};
    int myresult = 0;
    int oper = atoi(*++argv);
    printf("%d\n", oper);
    int mynum;
    while (*++argv != NULL) {
        mynum = atoi(*argv);
        printf("%d ", mynum);
        myresult = operate_func[oper](myresult, mynum);
    }
    printf("\n%d\n", myresult);
    return 0;
}

// ./test 0 1 13 52
// 0 ->参数含义是调用add函数,实际上是按照下标进行访问,
//  如果是 1 就调用sub函数。
// 1 13 52 -> 依次读取数据进行累加。
// 66 -> 最终累加和。


转载:https://blog.csdn.net/qq_21950671/article/details/108235385
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场