指向对象的常指针

合集下载

转载:C语言指针使用的注意事项

转载:C语言指针使用的注意事项

转载:C语⾔指针使⽤的注意事项相信⼤家对指针的⽤法已经很熟了,这⾥也不多说些定义性的东西了,只说⼀下指针使⽤中的注意事项吧。

⼀.在定义指针的时候注意连续声明多个指针时容易犯的错误,例如int * a,b;这种声明是声明了⼀个指向int类型变量的指针a和⼀个int型的变量b,这时候要清醒的记着,⽽不要混淆成是声明了两个int型指针。

⼆.要避免使⽤未初始化的指针。

很多运⾏时错误都是由未初始化的指针导致的,⽽且这种错误⼜不能被编译器检查所以很难被发现。

这时的解决办法就是尽量在使⽤指针的时候定义它,如果早定义的化⼀定要记得初始化,当然初始化时可以直接使⽤cstdlib中定义的NULL也可以直接赋值为0,这是很好的编程习惯。

三.指针赋值时⼀定要保证类型匹配,由于指针类型确定指针所指向对象的类型,因此初始化或赋值时必须保证类型匹配,这样才能在指针上执⾏相应的操作。

四.void * 类型的指针,其实这种形式只是记录了⼀个地址罢了,如上所说,由于不知道所指向的数据类型是什么所以不能进⾏相应的操作。

其实void * 指针仅仅⽀持⼏种有限的操作:1.与另外的指针进⾏⽐较,因为void *类型⾥⾯就是存的⼀个地址,所以这点很好理解;2.向函数传递void *指针或从函数返回void *指针,举个例⼦吧,我们平时常⽤的库函数qsort中的⽐较函数cmp(个⼈习惯于⽤这个名字)中传递的两个参数就是const void *类型的,⽤过的应该很熟了;3.给另⼀个void * 类型的指针赋值。

还是强调⼀下不能使⽤void * 指针操纵它所指向的对象。

五.不要将两个指针变量指向同⼀块动态内存。

这个容易引起很严重的问题。

如果将两个指针变量指向同⼀块动态内存,⽽其中⼀个⽣命期结束释放了该动态内存,这个时候就会出现问题,另⼀个指针所指向的地址虽然被释放了但该指针并不等于NULL,这就是所谓的悬垂指针错误,这种错误很难被察觉,⽽且⾮常严重,因为这时该指针的值是随机的,可能指向⼀个系统内存⽽导致程序崩溃。

C++课后习题及其答案

C++课后习题及其答案

练习题11.1 判断题×1.C++语言和C语言都是面向对象的程序设计语言。

√2.面向对象方法具有封装性、继承性和多态性。

√3.C语言是C++语言的一个子集。

C++语言继承了C语言。

×4.C++语言程序与C语言程序一样都是函数串。

×5.C++语言支持封装性和继承性,不支持多态性。

√6.C++语言比C语言对数据类型要求更加严格了。

√7.C++语言对C语言进行了一次改进,使得编程更加方便了。

×8.C++源程序在编译时可能出现错误信息,而在连接时不会出现错误信息。

√9.编译C++源程序时,出现了警告错(Warning)也可以生成可执行文件。

√10.C++语言程序的实现也要经过编辑、编译连接和运行3个步骤。

1.2 单选题1.下列关于面向对象概念的描述中,错误的是(C )。

A.面向对象方法比面向过程方法更加先进B.面向对象方法中使用了一些面向过程方法中没有的概念C.面向对象方法替代了结构化程序设计方法D.面向对象程序设计方法要使用面向对象的程序设计语言2.下列各种高级语言中,不是面向对象的程序设计语言是(D )。

A.C++ B.JavaC.VB D.C3.下列关于类的描述中,错误的是( A )。

A.类就是C语言中的结构类型B.类是创建对象的模板C.类是抽象数据类型的实现D.类是具有共同行为的若干对象的统一描述体4.下列关于对象的描述中,错误的是(C )。

A.对象是类的一个实例B.对象是属性和行为的封装体C.对象就是C语言中的结构变量D.对象是现实世界中客观存在的某种实体5.下列关于C++程序中使用提取符和插入符的输入/输出语句的描述中,错误的是(C )。

A.提取符是对右移运算符(>>)重载得到的B.插入符是对左移运算符(<<)重载得到的C.提取符和插入符都是双目运算符,它们要求有两个操作数D.提取符和插入符在输入/输出语句中不可以连用1.3 填空题1.C++语言具有面向对象方法中要求的三大特性:封装性、继承性和多态性。

java指针概念

java指针概念

java指针概念
Java是一种面向对象的编程语言,与C和C ++等语言不同,Java 不允许直接访问内存地址或使用指针。

Java指针是一种特殊类型的引用变量,它指向对象在内存中的地址。

Java中的指针类型是引用类型,Java中的所有引用类型都可以视为指针。

引用变量在Java中用于引用对象,并且可以使用该变量来访问对象的属性和方法。

Java的指针可以通过new关键字在堆上创建对象,使用该指针可以访问对象的属性和方法。

Java的指针通常用于传递对象引用作为参数,以便在方法之间共享数据。

Java的指针可以指向具有不同类型的对象,包括基本类型,数组和其他对象。

但是,Java不允许指针算术或对指针进行递增或递减操作。

Java中的指针有很多用途,例如在数据结构中使用指针来指向其他节点或指向某个数据结构的特定位置。

指针还可以用于在多线程环境中共享数据。

总之,Java中的指针是一种特殊类型的引用变量,它指向对象在内存中的地址,并用于访问对象的属性和方法。

Java中的指针通常用于传递对象引用作为参数,以便在方法之间共享数据。

- 1 -。

c++this的用法

c++this的用法

c++this的用法在C++中,this是一个特殊的指针,它指向当前对象的地址。

this常常在类方法中使用,用于在类方法中访问对象的成员变量和成员函数。

一、this的基本用法在类方法中,this指针指向调用该方法的对象。

通过使用this指针,可以在类方法中直接访问对象的成员变量和成员函数,而无需使用对象名。

例如:```cppclassMyClass{intx;public:voidsetX(intvalue){x=value;//直接访问成员变量,无需使用对象名}voidprintX(){cout<<x;//直接访问成员变量,无需使用对象名,也可以使用this->x}};```在上面的例子中,setX()和printX()都是类方法,它们都使用了this指针来访问对象的成员变量x。

二、this的注意事项1.避免重复使用对象名和this指针:在类方法中,尽量避免重复使用对象名和this指针来访问对象的成员变量和成员函数。

这会导致代码冗余和难以阅读。

2.使用this指针时需要小心指针赋值:如果一个类方法被另一个类方法返回,并且该方法返回一个指向当前对象的指针,那么这个指针需要使用对象的地址来赋值。

否则,会导致悬空指针或未定义的行为。

3.this指针是类的内部指针:this指针是类的内部指针,不应该被外部代码直接访问。

如果外部代码需要访问对象的成员变量和成员函数,应该使用对象名来访问。

4.this指针的传递:如果需要在类方法中使用其他类的方法,可以将this 指针作为参数传递给其他类的方法。

但是需要注意,传递this指针可能会导致代码难以理解和维护。

三、this的常见用法示例下面是一些使用this指针的常见用法示例:1.在构造函数中使用this指针:在构造函数中,可以使用this指针来访问对象的成员变量和成员函数。

例如:```cppclassMyClass{intx;public:MyClass(intvalue):x(value){}//使用this指针初始化成员变量x};```2.在析构函数中使用this指针:在析构函数中,可以使用this指针来释放对象的资源。

c++课后习题解答6-10

c++课后习题解答6-10
int elems[100],PC;
};
int S::IsMemberOf(int n)
{
for(int i=0;i<PC;i++)
if(elems[i]==n)
return 1;
return 0;
}
int S::Add(int n)
{
if(IsMemberOf(n))
return 1;
else if(PC==100)
√24.友元类中的所有成员函数都是友元函数。
√25.类型转换函数是一种特殊的成员函数,定义时不加类型说明,无函数参数。
√26.单参数的构造函数具有类型转换的作用。
6.2单选题
1.下列关于类的定义格式的描述中,错误的是(C)。
A.类中成员有3种访问权限
B.类的定义可分说明部分和实现部分
C.类中成员函数都是公有的,数据成员都是私有的
答:编程如下:
#include <iostream.h>
class ASMD
{
public:
ASMD(double a,double b)
{ x=a; y=b; }
void Addition()
{ cout<<x+y<<endl; }
void Subtration()
{ cout<<x-y<<endl; }
a.Print();
b.Print();
}
答:Default constructor called.
Constructor called.
a1=0,a2=0
a1=5,a2=8
Destructor called.

qt creator中this指针用法

qt creator中this指针用法

qt creator中this指针用法在Qt Creator中,"this"指针是一个指向当前对象的指针,它在C++中广泛使用。

在Qt Creator中,"this"指针的用法与在其他C++环境中类似。

下面是一些基本用法和例子:1. 成员函数中的使用:当你在类的成员函数中使用"this"指针时,它指向调用该成员函数的实例。

例如:```cppclass MyClass {public:void myFunction() {qDebug() << "This pointer is:" << this;}};```在这个例子中,`myFunction`是一个成员函数,当你调用这个函数的时候,"this"指针将指向调用这个函数的对象。

2. 重载操作符:在某些情况下,你可能需要重载操作符,如"->"。

在这些情况下,"this"指针可以用来区分重载的操作符和类的成员函数。

例如:```cppclass MyClass {public:MyClass operator->() {qDebug() << "This pointer in operator->: " << this;return this;}};```在这个例子中,"this"指针指向调用`operator->`的实例。

3. 动态分配对象:当你动态分配对象(即使用`new`关键字)时,"this"指针在构造函数中可用。

它指向新创建的对象。

例如:```cppclass MyClass {public:MyClass() {qDebug() << "This pointer in constructor: " << this;}};int main() {MyClass obj = new MyClass(); // This pointer will be printed here. delete obj;return 0;}```在这个例子中,"this"指针在`MyClass`的构造函数中被使用,它指向新创建的对象。

定义指向类函数的指针

定义指向类函数的指针

定义指向类函数的指针指向类函数的指针,简称为函数指针,在C++中是一种非常常用的数据类型。

它可以看做是指向类内部成员函数的指针,允许我们对类成员进行操作,是一种非常重要的工具。

在类中,函数指针可以被用来指向类的任意一个成员函数,以便我们在程序运行时动态地调用这些成员函数。

当我们将函数指针传递给一个函数或对象时,函数指针所指向的成员函数也将一起被传递,这样我们就可以在其他的程序片段中调用这些成员函数。

因此,函数指针在C++程序设计中具有非常重要的作用。

对于任意一个特定的类,我们可以定义对应的函数指针类型。

如果我们要使用某个对象的成员函数,我们需要创建一个这种类型的指针,并将它初始化为该对象的成员函数的地址。

然后,我们就可以通过这个指针来调用该对象的成员函数。

例如,假设我们有一个叫MyClass的类,其中定义了一个名为myfunc的成员函数,那么我们可以定义如下的函数指针类型:```typedef void (MyClass::*MyFuncPtr)();```上面的语句定义了一个名为MyFuncPtr的函数指针类型,该函数指针类型指向MyClass类中的一个返回类型为void、没有参数的成员函数。

接下来,我们就可以使用这个函数指针类型来创建一个指向某个特定对象的myfunc成员函数的指针:```MyClass obj;MyFuncPtr p = &MyClass::myfunc;```上面的语句将p初始化为obj对象的成员函数myfunc的地址。

这样,我们就可以通过p来调用该成员函数,如下所示:```(obj.*p)();```上面的语句调用了obj对象的myfunc成员函数。

总的来说,指向类函数的指针在C++中起到了非常重要的作用。

它允许我们在程序运行时动态地调用类成员函数,并且通过函数指针的传递和赋值等操作,可以使我们更加灵活地操作类成员函数。

因此,在C++程序设计中,函数指针是一项非常重要的工具,大家一定要充分了解和掌握。

C++中指针常量和常量指针的区别

C++中指针常量和常量指针的区别

C++中指针常量和常量指针的区别在C++学习使⽤过程中,每个⼈都不可避免地使⽤指针,⽽且都或多或少的接触过常量指针或指针常量,但是对这两个的概念还是很容易搞糊涂的。

本⽂即是简单描述指针常量和常量指针的区别。

常量指针 定义:⼜叫常指针,可以理解为常量的指针,也即这个是指针,但指向的是个常量,这个常量是指针的值(地址),⽽不是地址指向的值。

关键点:1.常量指针指向的对象不能通过这个指针来修改,可是仍然可以通过原来的声明修改;2.常量指针可以被赋值为变量的地址,之所以叫常量指针,是限制了通过这个指针修改变量的值;3.指针还可以指向别处,因为指针本⾝只是个变量,可以指向任意地址; 代码形式:int const* p; const int* p;指针常量定义:本质是⼀个常量,⽽⽤指针修饰它。

指针常量的值是指针,这个值因为是常量,所以不能被赋值。

关键点:1.它是个常量!2.指针所保存的地址可以改变,然⽽指针所指向的值却不可以改变;3.指针本⾝是常量,指向的地址不可以变化,但是指向的地址所对应的内容可以变化; 代码形式:int* const p;指向常量的常指针 定义: 指向常量的指针常量就是⼀个常量,且它指向的对象也是⼀个常量。

关键点:1.⼀个指针常量,指向的是⼀个指针对象;2.它指向的指针对象且是⼀个常量,即它指向的对象不能变化;代码形式:const int* const p;那如何区分这⼏类呢? 带两个const的肯定是指向常量的常指针,很容易理解,主要是如何区分常量指针和指针常量:⼀种⽅式是看 * 和 const 的排列顺序,⽐如int const* p; //const * 即常量指针const int* p; //const * 即常量指针int* const p; //* const 即指针常量还⼀种⽅式是看const离谁近,即从右往左看,⽐如int const* p; //const修饰的是*p,即*p的内容不可通过p改变,但p不是const,p可以修改,*p不可修改;const int* p; //同上int* const p; //const修饰的是p,p是指针,p指向的地址不能修改,p不能修改,但*p可以修改;看代码:1//-------常量指针-------2const int *p1 = &a;3 a = 300; //OK,仍然可以通过原来的声明修改值,4//*p1 = 56; //Error,*p1是const int的,不可修改,即常量指针不可修改其指向地址5 p1 = &b; //OK,指针还可以指向别处,因为指针只是个变量,可以随意指向;67//-------指针常量-------//8int* const p2 = &a;9 a = 500; //OK,仍然可以通过原来的声明修改值,10 *p2 = 400; //OK,指针是常量,指向的地址不可以变化,但是指向的地址所对应的内容可以变化11//p2 = &b; //Error,因为p2是const 指针,因此不能改变p2指向的内容1213//-------指向常量的常量指针-------//14const int* const p3 = &a;15//*p3 = 1; //Error16//p3 = &b; //Error17 a = 5000; //OK,仍然可以通过原来的声明修改值在实际应⽤中,常量指针要⽐指针常量⽤的多,⽐如常量指针经常⽤在函数传参中,以避免函数内部修改内容。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

指向对象的常指针将指针变量声明为const型,这样指针值始终保持为其初值,不能改变。

如:Time t1(10,12,15),t2; //定义对象Time * const ptr1; //const位置在指针变量名前面,规定ptr1的值是常值ptr1=&t1; //ptr1指向对象t1,此后不能再改变指向ptr1=&t2; //错误,ptr1不能改变指向定义指向对象的常指针的一般形式为:类名* const 指针变量名;也可以在定义指针变量时使之初始化,如将上面第2, 3行合并为:Time * const ptr1=&t1; //指定ptr1指向t1请注意,指向对象的常指针变量的值不能改变,即始终指向同一个对象,但可以改变其所指向对象(如t1)的值。

指向常对象的指针变量下面定义了一个指向常变量的指针变量ptr:const char *ptr;注意const的位置在最左侧,它与类型名char紧连,表示指针变量ptr指向的char变量是常变量,不能通过ptr来改变其值的。

定义指向常变量的指针变量的一般形式为:const 类型名*指针变量名;几点说明:1) 如果一个变量已被声明为常变量,只能用指向常变量的指针变量指向它,而不能用一般的(指向非const型变量的)指针变量去指向它。

如:const char c[] ="boy"; //定义const 型的char 数组const char * pi; //定义pi为指向const型的char变量的指针变量pi =c; //合法,pi指向常变量(char数组的首元素)char *p2=c; //不合法,p2不是指向常变量的指针变量2) 指向常变量的指针变量除了可以指向常变量外,还可以指向未被声明为const的变量。

此时不能通过此指针变量改变该变量的值。

如:char cl ='a'; //定义字符变量cl,它并未声明为constconst char *p; //定义了一个指向常变量的指针变量pp = &cl; //使p指向字符变量cl*p = 'b'; //非法,不能通过p改变变量cl的值cl = 'b'; //合法,没有通过p访问cl,cl不是常变量3) 如果函数的形参是指向非const型变量的指针,实参只能用指向非const变量的指针,而不能用指向const变量的指针,这样,在执行函数的过程中可以改变形参指针变量所指向的变量(也就是实参指针所指向的变量)的值。

如果函数的形参是指向const型变量的指针,在执行函数过程中显然不能改变指针变量所指向的变量的值,因此允许实参是指向const变量的指针,或指向非const变量的指针。

如:const char str[ ] = "boy"; //str 是const 型数组名void fun( char * ptr) ; //函数fun的形参是指向非const型变量的指针fun(str); //调用fun函数,实参是const变量的地址,非法因为形参是指向非const型变量的指针变量,按理说,在执行函数过程中它所指向的变量的值是可以改变的。

但是形参指针和实参指针指向的是同一变量,而实参是const 变量的地址,它指向的变量的值是不可改变的。

这就发生矛盾。

因此C++要求实参用非const变量的地址(或指向非const变量的指针变量)。

(* p).hour = 18; //非法,不齙通过指针变量改变t1的值如果希望在任何情况下t1的值都不能改变,则应把它定义为const型,如:const Time t1(lO,12,15);请注意指向常对象的指针变量与指向对象的常指针变量在形式上和作用上的区别。

Time * const p; //指向对象的常指针变量const Time *p; //指向常对象的指针变量3) 指向常对象的指针最常用于函数的形参,目的是在保护形参指针所指向的对象,使它在函数执行过程中不被修改。

请记住这样一条规则:当希望在调用函数时对象的值不被修改,就应当把形参定义为指向常对象的指针变量,同时用对象的地址作实参(对象可以是const或非const型)。

如果要求该对象不仅在调用函数过程中不被改变,而且要求它在程序执行过程中都不改变,则应把它定义为const型。

4) 如果定义了一个指向常对象的指针变量,是不能通过它改变所指向的对象的值的,但是指针变量本身的值是可以改变的。

对象的常引用我们知道,一个变量的引用就是变量的别名。

实质上,变量名和引用名都指向同一段内存单元。

如果不希望在函数中修改实参t1的值,可以把引用变量t声明为const(常引用),函数原型为void fun(const Time &t);则在函数中不能改变t的值,也就是不能改变其对应的实参t1的值。

如果形参为变量的引用名,实参为变量名,则在调用函数进行虚实结合时,并不是为形参另外开辟一个存储空间(常称为建立实参的一个拷贝),而是把实参变量的地址传给形参(引用名),这样引用名也指向实参变量。

静态数据成员关于静态数据成员的几点说明:1) 如果只声明了类而未定义对象,则类的一般数据成员是不占内存空间的,只有在定义对象时,才为对象的数据成员分配空间。

但是静态数据成员不属于某一个对象,在为对象所分配的空间中不包括静态数据成员所占的空间。

静态数据成员是在所有对象之外单独开辟空间。

只要在类中定义了静态数据成员,即使不定义对象,也为静态数据成员分配空间,它可以被引用。

在一个类中可以有一个或多个静态数据成员,所有的对象共享这些静态数据成员,都可以引用它。

2) 对于静态变量,如果在一个函数中定义了静态变量,在函数结束时该静态变量并不释放,仍然存在并保留其值。

静态数据成员也类似,它不随对象的建立而分配空间,也不随对象的撤销而释放(一般数据成员是在对象建立时分配空间,在对象撤销时释放)。

静态数据成员是在程序编译时被分配空间的,到程序结束时才释放空间。

3) 静态数据成员可以初始化,但只能在类体外进行初始化。

如int Box::height=10; //表示对Box类中的数据成员初始化其一般形式为:数据类型类名::静态数据成员名=初值;不必在初始化语句中加static。

注意,不能用参数对静态数据成员初始化。

如在定义Box类中这样定义构造函数是错误的:Box(int h,int w,int len):height(h){ } //错误,height是静态数据成员如果未对静态数据成员赋初值,则编译系统会自动赋予初值0。

4) 静态数据成员既可以通过对象名引用,也可以通过类名来引用。

静态成员函数与数据成员类似,成员函数也可以定义为静态的,在类中声明函数的前面加static就成了静态成员函数。

如static int volume( );和静态数据成员一样,静态成员函数是类的一部分,而不是对象的一部分。

如果要在类外调用公用的静态成员函数,要用类名和域运算符“::”。

如Box::volume( );实际上也允许通过对象名调用静态成员函数,如a.volume( );但这并不意味着此函数是属于对象a的,而只是用a的类型而已。

与静态数据成员不同,静态成员函数的作用不是为了对象之间的沟通,而是为了能处理静态数据成员。

可以说,静态成员函数与非静态成员函数的根本区别是:非静态成员函数有this指针,而静态成员函数没有this指针。

由此决定了静态成员函数不能访问本类中的非静态成员。

静态成员函数可以直接引用本类中的静态数据成员,因为静态成员同样是属于类的,可以直接引用。

在C++程序中,静态成员函数主要用来访问静态数据成员,而不访问非静态成员。

友元(友元函数和友元类)如果在本类以外的其他地方定义了一个函数(这个函数可以是不属于任何类的非成员函数,也可以是其他类的成员函数),在类体中用friend对其进行声明,此函数就称为本类的友元函数。

友元函数可以访问这个类中的私有成员。

1) 将普通函数声明为友元函数friend void display(Time &); //声明display函数为Time类的友元函数2) 友元成员函数friend函数不仅可以是一般函数(非成员函数),而且可以是另一个类中的成员函数。

include <iostream>using namespace std;class Date; //对Date类的提前引用声明class Time //定义Time类{public:Time(int,int,int);void display(Date &); //display是成员函数,形参是Date类对象的引用private:int hour;int minute;int sec;};class Date {//声明Date类public:Date(int,int,int);friend void Time::display(Date &); //声明Time中的display函数为友元成员函数private:int month;int day;int year;};3) 一个函数(包括普通函数和成员函数)可以被多个类声明为“朋友”,这样就可以引用多个类中的私有数据。

友元类友元类B中的所有函数都是A类的友元函数,可以访问A类中的所有成员。

在A类的定义体中用以下语句声明B类为其友元类:friend B;声明友元类的一般形式为:friend 类名;关于友元,有两点需要说明:∙友元的关系是单向的而不是双向的。

如果声明了B类是A类的友元类,不等于A类是B类的友元类,A类中的成员函数不能访问B类中的私有数据。

∙友元的关系不能传递,如果B类是A类的友元类,C类是B类的友元类,不等于C类是A 类的友元类。

例如,张三的好友是李四,而李四有好友王五,显然,王五不一定是张三的好友。

如果想让C类是A类的友元类,应在A类中另外声明。

类模板1) 声明类模板时要增加一行template <class 类型参数名>类型参数可以不只一个,可以根据需要确定个数。

如:template <class T1, typename T2>运算符重载At least one argument of an overloaded operator must be of a class typeAn overloaded operator can be a friend of a classNew operators cannot be createdThe number of arguments for an operator cannot be changedThe precedence of an operator cannot be changed., ::, *., and ? cannot be overloaded重载运算符的函数一般格式如下:函数类型operator 运算符名称(形参表列){// 对运算符的重载处理}一元// prefixfriend Circle operator ++(Circle& aCircle);// postfixfriend Circle operator ++(Circle& aCircle, int increment);二元Complex operator+ (Complex& c1, Complex& c2);输入输出friend ostream& operator << (ostream&,Complex&); //声明重载运算符“<<”friend istream& operator >> (istream&,Complex&); //声明重载运算符“>>”派生类的构成1) 从基类接收成员派生类把基类全部的成员(不包括构造函数和析构函数)接收过来,也就是说是没有选择的,不能选择接收其中一部分成员,而舍弃另一部分成员。

相关文档
最新文档