public: int speed; }; int main() { int Car::*pSpeed = &Car::speed; return 0; } 为什么这个指针要指向一个非静态类成员...这种奇怪的用法有什么用?...< count_fruit(bowls, bowls + 2, & bowl::oranges) << " oranges\n"; return 0; } 关注点在于 count_fruit 的第三个参数...,这样就省去了单独编写 count_apples 和 count_oranges 函数的麻烦。
在C++中,可以定义一个指针,使其指向类成员或成员函数,然后通过指针 来访问类的成员。这包括指向属性成员的指针和指向成员函数的指针。它类似与static成员函数或成员变量,具有共享的属性。...每一个实例化的对象都可以借助指向类数据成员的指针来访问指向的数据。...所以我们还是一样要通过成员函数来操作,同样,成员函数一样可以拥有一个属于自己的指针。...*pf)(); (ps3->*pf)(); getchar(); return 0; } 以上均是指向非静态成员的类成员指针,而指向静态类成员的指针则非常简单。...●指向类静态成员函数的指针 指向静态成员函数的指针和普通指针相同,在定义时无须和类相关联,在使用时也 无须和具体的对象相关联。
,原文详细解释了C++中指向成员函数的指针,因为带有“教程”一词,所以比较通俗易懂。...*fptr 绑定fptr到对象obj,而 ->*fptr 则绑定fptr到指针p所指向的对象。(还有一个 重要的区别 是:我们可以重载后者,却不能重载前者)。在 (obj....上述代码中字符串来源是两个字符串常量"Strings "和"concatenated!",而成员函数指针数组被用来根据菜单选项执行相应的打印动作。...成员函数调用和 this 指针 现在我们回到文章最开始的地方。为什么一个空指针也能调用成员函数?...成员函数指针和常规指针的对比 不同情形下的成员函数指针转换规则 如何使用成员函数指针数组来解决特定的设计问题 编译器是如何解释成员函数调用的 扩展:成员变量指针 http://luodw.cc/2015
在指针常量中,指针自身的值是一个常量,不可改变,始终指向同一个地址。在定义的同时必须初始化。...int *p, int const *p) 常量指针本质上是一个指针,常量表示指针指向的内容,说明该指针指向一个“常量”。...在常量指针中,指针指向的内容是不可改变的,指针看起来好像指向了一个常量。...错误,指针常量不能在定义后赋值 const int * const ptr6 = &m; // 指向“常量”的指针常量,具有常量指针和指针常量的特点,指针内容不能改变,也不能指向其他地方,定义同时要进行初始化...”并返回其首地址,此时str由指向字符串常量”apple”的首地址变为指向字符串常量”orange”的首地址,str指向的地址发生了变化,但str是指针常量不能被修改,所以错误。
void fun(int age, int height) const const 修饰的是 fun 函数的 第一个参数 Student* pThis 指针指向的内存空间 ; C++ 编译器会将 void..., 其本质是修饰 第一个参数 Student* pThis 指针指向的内存空间 和 指针本身 ; 将 void fun(int age, int height) const 转换为 C 语言代码为...函数的 第一个参数 Student* pThis 指针指向的内存空间 和 指针本身 // // C++ 编译器会将该函数转为 Student_fun(Student* pThis, int age...其它常量成员函数 如果类的 成员变量 不是 常量 , 那么 " 常量成员函数 " 不能访问它们 ; public: int age; // 年龄 int height; // 身高 如果类的...fun 函数的 第一个参数 Student* pThis 指针指向的内存空间 和 指针本身 // // C++ 编译器会将该函数转为 Student_fun(Student* pThis, int
C++中this指针是一个指向当前对象的指针。在成员函数中,可以使用this指针来访问调用该函数的对象的成员变量和成员函数。...一、定义和使用this指针 this指针是在成员函数内部定义的一个常量指针。它存储了当前对象的地址,可以通过它访问当前对象的成员变量和成员函数。...二、作为返回值的this指针 this指针可以作为返回值返回。这种情况下,返回的是指向调用该函数的对象的指针。为了实现这个功能,需要将返回类型设置为类的引用或指针类型。...,返回的是指向调用该函数的对象的指针。...这里使用了*this来访问调用该函数的对象。 三、作为函数参数的this指针 this指针也可以作为函数参数传递。这种情况下,可以在函数内部访问其他对象的成员变量和成员函数。
一个静态成员函数不与任何对象相联系,故不能对非静态成员进行默认访问。 它们的根本区别在于静态成员函数没有this指针,而非静态成员函数有一个指向当前对象的指针this。...4 void nsfn(int a); //像声明Sc::nsfn(Sc *this , int a); 5 static void sfn(int a); // 无this指针...对nsfn()的调用,编译像注解的那样进行转换,s的地址作为第一个传递的参数。(你并不实际写该调用,由编译来实现。)...在函数内部,Sc::nsfn()对非静态成员的访问将自动把this参数作为指向当前对象的指针。而当Sc::sfn()被调用时,没有任何对象的地址被传递。因此,当访问非静态成员时,无this指针出错。...这就是为什么一个静态成员函数与任何当前对象都无联系的原因。
接上一篇 VC和GCC内成员函数指针实现的研究(二) 虚继承 终于到最后的虚继承了。...image.png 图十七:VC多重虚继承的取成员变量和虚基类成员变量 GCC虚继承成员函数指针实现 同样,赋值部分没什么特别的,和前面都一样。...经过测试,GCC在空虚基类成员函数指针调用和非空虚基类不同,我们直接上调用的汇编。...:一个指针指向一个跳转函数,另一个指针里面保存偏移量,然后执行的时候根据偏移量来计算实际地址的。...用foo_c的指针去调用foo_b的成员函数的时候是需要对指针值做些offset修正的。 然而 获取成员函数指针和成员函数调用是分开的场景。
*ptr)(); return 0; } VC多重继承成员函数指针实现 image.png 图八:VC多重继承的指针赋值操作 赋值的部分和单继承是一样的。...image.png 图十:VC多重继承的虚表 (和前面不是同一批的截图,可能地址会对不上) 可以看到c和b的foo_b类型的虚表的info函数指向的地址是不同的。...GCC多重继承成员函数指针实现 image.png 图十二:GCC多重继承的函数指针赋值 哈,GCC的多重继承的赋值部分也和单继承一样,那么调用呢?...image.png 图十三:GCC多重继承的函数指针调用 如上图所示,比单继承多了两行,第一行是调整虚表地址到foo_b,这点和VC一样。后面增加的add指令是调整成员函数的this指针地址。...下一篇 VC和GCC成员函数指针实现的研究(三)
重载双目运算符时,运算符函数中应该具有两个参数,若运算符函数作为类的成员函数(当运算符重载函数作为类的成员函数时,要求操作数左边必须是一个对象,而函数的参数可以是同类的对象也可以是普通的变量),则只需要一个参数...双目运算符 双目运算符就是具有两个操作数的运算符。如 +、-、==等。 对双目运算符而言,成员函数重载运算符的函数参数表中只有一个参数,而用友元函数重载运算符函数参数表中含有两个参数。...成员函数重载 == 、>运算符: bool operator==(CTime& time); bool operator>(CTime& time); //判断对象的每个成员变量是否相等...,返回false } 成员函数重载++运算符 CTime operator++();//前置的++ CTime operator++(int);//后置++,这个int类型的参数只是为了区分...定义了一个秒数为1的对象 *this = *this + time;//由于前面的函数已经重载了加号运算符,里面已经定义好了相关的操作,所以这句代码调用了加号运算符的重载函数,并将对象的秒数加一
一、运算符重载本质 运算符重载的本质是 " 函数调用 " ; 当使用 + 将 个对象相加时 , C++ 编译器会查找是否有定义运算符重载函数 ; // 自定义类型相加 Student s1(10,...二、运算符重载语法 - 类内部定义云算符重载 ( 成员函数 ) 1、运算符重载函数语法说明 C++ 中允许重新定义运算符的行为 , 如常用的加减成熟运算符 , 都可以进行重载操作 ; 可以自定义运算符的操作..., 可以使用函数形式调用 , 也可以使用运算符进行运算 , 其 本质还是类的函数调用 ; 2、运算符重载函数调用 重载运算符完整调用 , 即调用上面定义的整个 operator+ 方法 , 这是采用正式的的函数调用方式...: 90 三、运算符重载语法 - 类外部定义运算符重载 ( 全局函数 ) ---- 1、运算符重载函数语法说明 类外部定义运算符重载 , 运算符重载也可以定义在类的外部 , 可以是任意包含类头文件的代码中..., 其number成员变量值是 o1 和 o2 中number成员变量之积 Operator o6 = o1 * o2; //打印 o6 中的 number 变量值 cout << "外部定义的运算符重载简化写法结果
以String类为例实现其成员函数 class String { //友元函数重载运算符 friend ostream& operator<<(ostream &out,String& str);...str) //对m_data加NULL判断 { length = 0; m_data = new char[1]; //对空字符串自动申请存放结束标志'\0'的空 *m_data...inline size_t size() const { return length; } private: char* m_data; size_t length; }; //为什么要重载为友元函数.../*如果是双目运算符,只要设置一个参数作为右侧运算量,左侧运算符就是对象this本身 *但是>>或<<左侧运算符是cin或cout而不是对象本身,只能声明为友元了 *如果一定要声明为成员函数,只能声明为...ostream & operator<<(ostream &output) *在运用这个<<运算符时就变为这种形式了:data<<cout;不合符人的习惯。
const 可以用来修饰成员变量和成员函数。 const成员变量 const 成员变量的用法和普通 const 变量的用法相似,只需要在声明时加上 const 关键字。...const成员函数(常成员函数) const 成员函数可以使用类中的所有成员变量,但是不能修改它们的值,这种措施主要还是为了保护数据而设置的。const 成员函数也称为常成员函数。...常成员函数需要在声明和定义的时候在函数头部的结尾加上 const 关键字,请看下面的例子: class Student{ public: Student(char *name...需要强调的是,必须在成员函数的声明和定义处同时加上 const 关键字。...char *getname() const和char *getname()是两个不同的函数原型,如果只在一个地方加 const 会导致声明和定义处的函数原型冲突。
题目: 类成员函数的重载、覆盖和隐藏区别描述正确的有?...A、覆盖是指在同一个类中名字相同,参数不同 B、重载是指派生类函数覆盖基类函数,函数相同,参数相同,基类函数必须有virtual关键字 C、派生类函数与基类函数相同,但是参数不同,会"隐藏"父类函数 D...、函数名字相同,参数相同,基类无virtual关键字的派生类的函数会"隐藏"父类函数 答案: CD 解析: a.成员函数被重载的特征: (1)相同的范围(在同一个类中); (2)函数名字相同;...“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下: (1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。...(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。
*ptr)(); return 0; } 先不展示这段代码的输出结果。这里面只有一层继承,分别有虚函数和非虚函数。并且都有指针赋值和执行操作。不出所料的是,(b....那么,VC和GCC是怎么实现这一功能的呢 VC单继承成员函数指针实现 image.png 图一: VC指针赋值 可以看到,对非虚函数指针,直接把函数地址赋值过去了,但是对于虚函数,赋值的并不是foo_a...往下看函数调用: image.png 图六:GCC单继承下成员函数指针调用 可以看到,GCC的成员函数指针和VC的设计明显不同。...但是这种做法带来的缺陷就是类成员函数指针比VC多消耗了一倍的内存,执行结果如下: image.png 图七:GCC单继承测试代码执行结果 多重继承和虚继承的分析就下次再来啦。...下一篇 VC和GCC成员函数指针实现的研究(二)
*ptr)(); return 0; } 先不展示这段代码的输出结果。这里面只有一层继承,分别有虚函数和非虚函数。并且都有指针赋值和执行操作。不出所料的是,(b....那么,VC和GCC是怎么实现这一功能的呢 VC单继承成员函数指针实现 图片 图一: VC指针赋值 可以看到,对非虚函数指针,直接把函数地址赋值过去了,但是对于虚函数,赋值的并不是foo_a::info...往下看函数调用: 图片 图六:GCC单继承下成员函数指针调用 可以看到,GCC的成员函数指针和VC的设计明显不同。...但是这种做法带来的缺陷就是类成员函数指针比VC多消耗了一倍的内存,执行结果如下: 图片 图七:GCC单继承测试代码执行结果 多重继承和虚继承的分析就下次再来啦。...下一篇 VC和GCC成员函数指针实现的研究(二)
其实上述的行为都由this指针左右结果。 0x00 静态函数没有this指针 静态方法随着类的加载而加载,静态方法不需要实例化。...0x01 成员函数不使用this指针不报错 a->print();可以近似看作void print(A *a): void print(A *a) { printf("+++++\n"); }... 由此A的实例a指针没有被使用,不会访问到错误的地址而出现异常。...0x02 空指针引用实例成员才会异常 void print3()中使用了实例a的value成员,由于a为空,没有指向具体的内存,导致引用value内存出错。...0x03 总结 上述行为引起段错误的原因是空指针实例引用了成员变量导致的。
sum以及每件商品的平均售价。...要求用静态数据成员和静态成员函数。 (提示: 将折扣discount,总销售款sum和商品销售总件数n声明为静态数据成员,再定义静态成员函数average(求平均售价)和display(输出结果)。...average(); shop::dispaly(); } 运行结果: 101销售117.5 102销售288.826 103销售2107 单价为21.4814总销售额为2513.33 备注: 静态函数是类的一部分不是对象的一部分...静态成员没有this指针。...静态成员必须进行初始化 初始化方式在类外进行 例如:int shop::n=0; 静态函数引用可以通过shop::dispaly();形式,也可以通过a[0].dispaly();,但是只是借用了a[0
C++程序的内存格局通常分为四个区: 全局数据区(data area),代码区(code area),栈区(stack area),堆区(heap area)(即自由存储区)。...全局数据区存放全局变量,静态数据和常量; 所有类成员函数和非成员函数代码存放在代码区; 为运行函数而分配的局部变量、函数参数、返回数据、返回地址等存放在栈区;余下的空间都被称为堆区。...根据这个解释,我们可以得知在类的定义时,类成员函数是被放在代码区,而类的静态成员变量在类定义时就已经在全局数据区分配了内存,因而它是属于类的。...对于非静态成员变量,我们是在类的实例化过程中(构造对象)才在栈区或者堆区为其分配内存,是为每个对象生成一个拷贝,所以它是属于对象的。
operator操作符(参数列表); 运算符重载的函数的调用和一般的函数也是一样的,只不过运算符重载的函数名有点特殊而已。...4.作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐 藏的this; 5. .* :: sizeof ?...3.返回*this :要符合连续赋值的含义; 注意: 赋值运算符只能重载成类的成员函数不能重载成全局函数,因为重载成全局的,类里面又会自动生成一个,这样编译器就无法分辨; 如果没有显示定义赋值运算符重载...,那么会自动生成的赋值运算符重载,这和拷贝构造函数类似: 1.对内置类型完成浅拷贝; 2.对自定义类型会去调用它的赋值运算符重载函数 下面是日期类的赋值运算符重载: Date& operator...四.区分拷贝构造和赋值运算符重载 1.当我们用一个已经存在对象去初始化另一个对象时,即使写的是 “ = ” ,此时也调用它的拷贝构造函数; 2.已经存在的两个对象之间赋值拷贝,此时是赋值运算符重载;
领取专属 10元无门槛券
手把手带您无忧上云