在C语言中如何存储并初始化成员变量

在C语言中如何存储并初始化成员变量,第1张

成员变量必须在构造函数的初始化列表中完成初始化。SMART pointer members minimize dependencies while allowing exception safety。通过以指针存储成员变量的方法最小化依赖// Userhclass PointerMember;class RefParam;class User{public:User( const RefParam &inParam );virtual ~User();private:PointerMember mPointerMember;};// Usercpp#include UserhUser::User( const RefParam &inParam ): mPointerMember( new PointerMember( inParam ) ){return;}User::~User(){delete mPointerMember;return;}这样当你要使用成员变量时,原来使用mValMemberSomething的地方就要用mPointerMember-Something了。文本编辑器或者集成开发环境的查询替换方法可以很容易地在切换存储方法。初始化列表注意,在构造函数初始化列表中初始化对象的指针成员(可以是任何类型成员)是非常重要的。对于C++的初学者来说,像上面的例子中所看到的,下面语句位于大括号之前看起来感觉非常别扭。: mPointerMember( new PointerMember( inParam ) )在类对象的生命周期中,如果实际应用时不需要经常使用指针成员变量时,可以选择将该指针成员初始化为nil(注意:删除一个nil指针永远是安全的。因为delete方法的实现在将指针变量传递给堆管理器前,首先检验指针的值)。如果指针变量需要在构造之前分配存储空间的话,一定要在初始化列表中完成,而不像下面代码一样在构造函数体中完成。User::User( const RefParam &inParam ){mPointerMember = new PointerMember( inParam ); // DON'T DO THISreturn;}我所工作的大型C++项目中,那些很少使用初始化列表初始化成员变量的,都到处充斥着错误。其中有一个项目,源码共70多兆,我在那家公司工作的时候除了调试错误没做其他任何事情。搞定了一摞错误,又会出现一筐错误。适当的初始化成员变量失败不只是代码的问题,还与更高层次问题相关。一般来说,构造函数体应该只用来开展对成员变量的 *** 作,或者是全部完成初始化后对整个对象的 *** 作。基本原则是保留函数体给不适合由初始化列表完成的代码。开始学习适当的使用初始化列表以来,在写信构造函数或者重写老的构造函数后,函数体往往是空的,或者仅包含不多的几行代码,因为全部的实际工作都在初始化列表中完成了。要完成这些工作有时候需要一些额外的工作,但是最后还是能把这些工作量找回来的。

account::account(char

Name,int

Id)//这里只是传递值进来,在这个

构造函数

调用完后,这个值也就释放了,所以即使保存这个值的指针也没用,LZ应该把这个值的地址传进来,如:

account::account(char

Name,int

Id)

{

name

=

new

char[strlen(Name)+1];

strcpy(name,Name);

/id

=

new

int;/

id

=

Id;

cout<<id<<endl;

}

在main函数中改为:

int

b=123

account

a("abc",&b);

agetaccount();

问题:(一)中的studentname并未初始化,为什么能赋值成功?

stuname = "jim"; "jim"; 是字符串常量,系统自动为他分配了内存并保存这些字符,执行赋值 *** 作是,将这个字符串的首地址复制给 stuname。

(二)偶用strcpy_s函数时有疑问,strcpty(str1,int,str2)中 sizeof(str1)>int&&int>sizeof(str2)

strcpy_s和strcpy()函数的功能几乎是一样的。strcpy函数,就象gets函数一样,它没有方法来保证有效的缓冲区尺寸,所以它只能假定缓冲足够大来容纳要拷贝的字符串。在程序运行时,这将导致不可预料的行为。用strcpy_s就可以避免这些不可预料的行为。

这个函数用两个参数、三个参数都可以,只要可以保证缓冲区大小。

三个参数时:

errno_t strcpy_s(

char strDestination,

size_t numberOfElements,

const char strSource

);

两个参数时:

errno_t strcpy_s(

char (&strDestination)[size],

const char strSource)

例如:

char str1=NULL;

str1=new char[20];

char str[7];

strcpy_s(str1,20,"hello world");//三个参数

strcpy_s(str,"hello");//两个参数但如果:char str=new char[7];会出错:提示不支持两个参数

《面向对象程序设计》第03章在线测试

剩余时间:

57:18

答题须知:1、本卷满分20分。

2、答完题后,请一定要单击下面的“交卷”按钮交卷,否则无法记录本试卷的成绩。

3、在交卷之前,不要刷新本网页,否则你的答题结果将会被清空。

第一题、单项选择题(每题1分,5道题共5分)

1、假定AA为一个类,a为该类公有的数据成员,若要在该类的一个成员函数中访问它,则书写格式为(A )。

A、a B、AA::a

C、a() D、AA::a()

2、在关键字public后面定义的成员为类的(B )成员。

A、私有 B、公用

C、保护 D、任何

3、假定 ab 为一个类,则执行 ab x ;语句时将自动调用该类的 ( B) 。

A、有参构造函数 B、无参构造函数

C、拷贝构造函数 D、赋值构造函数

4、一段程序的定义如下,在函数f()中将动态对象的成员n的值改为34的语句应该为 ( C) class A { int n; public: setn(int nl) {n=nl;} A(int x) {n = x; } } int f() {A ptr = new A(45); }

A、An=34; B、ptrsetn(34);

C、ptr->setn(34); D、setn(34);

5、假定AB为一个类,则执行“AB p=new AB(1,2);”语句时共调用该类构造函数的次数为(B )。

A、0 B、1

C、2 D、3

第二题、多项选择题(每题2分,5道题共10分)

1、下列可以作为类的成员的是( ACD)

A、自身类对象的指针

B、自身类对象

C、自身类对象的引用

D、另一个类的对象

2、关于封装,下列说法中正确的是(ABC )。

A、通过封装,对象的全部属性和 *** 作结合在一起,形成一个整体

B、通过封装,一个对象的实现细节被尽可能地隐藏起来(不可见)

C、通过封装,每个对象都成为相对独立的实体

D、通过封装,对象的属性都是不可见的

3、定义析构函数时,错误的说法是 ( ABD) 。

A、其名与类名完全相同

B、返回类型是 void 类型

C、无形参,也不可重载

D、函数体中必须有 del_ete 语句

4、下面关于静态数据成员的说法错误的是(BCD )

A、静态数据成员是类的所有对象所共有的

B、静态数据成员要在构造函数内初始化

C、类的每个对象有自己的静态数据成员

D、静态数据成员不能通过类的对象调用

5、下列描述属于类的成员函数的是(ABD )

A、构造函数

B、析构函数

C、友元函数

D、拷贝构造函数

第三题、判断题(每题1分,5道题共5分)

1、假定AA为一个类,a为该类公有的数据成员,x为该类的一个对象,则访问x对象中数据成员a的格式为x->a。 F

正确 错误

2、对类中引用成员的初始化是通过构造函数中给出的初始化表实现的。T

正确 错误

3、析构函数的作用是在对象被撤销时收回先前分配的内存空间。T

正确 错误

4、使用关键字class 定义的类中缺省的访问权限是私有private的。T

正确 错误

5、当两个对象之间进行复制时,复制完成后这两个对象的内容将完全独立,没有关联。 F

正确 错误

对于类对象对于成员的调用,需要有类对象的限定,一方面是一个类命名空间,另一方面用于传递隐含的this指针。

数据和函数,包括类对象的数据成员和成员函数,都是可以寻址的,自然也可以定义一个指针,使其指向类成员或成员函数,然后通过指针来访问类的成员。这包括指向属性成员的指针和指向成员函数的指针。

关于数据的指针变量存储了具有特定数据类型的一个内存空间的首地址,确定了其指向的目标对象的蓝图,核心是由数据类型确定了目标对象所需内存空间大小,数据类型的编码和解码方式。关于代码的指针变量是指指向函数的指针变量,同样是首地址,类型是由函数签名所确定的类型,以及代码的指令集编码及读取和译码方式。

21 指向类数据成员的指针

211 定义

为了区别于普通指针变量,多了一个类名作用域限定,也显示了与类及类成员的相关性。

212 赋值&初始化

指向非静态数据成员的指针在定义时必须和类相关联,在使用时必须和具体的对象关联。

213 解引用

由于类不是运行时存在的对象。因此,在使用这类指针时,需要首先指定类的一个对象,然后,通过对象来引用指针所指向的成员。

示例代码:

22 指向类成员函数的指针

定义一个指向非静态成员函数的指针必须在三个方面与其指向的成员函数保持一致:参数列表要相同、返回类型要相同、所属的类型要相同。

221 定义

为了区别于全局函数指针,多了一个类名作用域限定,也显示了与类及类成员的相关性。

222 赋值&初始化

223 解引用

由于类不是运行时存在的对象。因此,在使用这类指针时,需要首先指定类的一个对象,然后,通过对象来引用指针所指向的成员。

示例代码:

指向非静态成员时,必须用类名作限定符,使用时则必须用类的实例作限定符。指向静态成员时,声明时则不需要使用类名作限定符。(当然静态成员做右值也需要类名限定)

用指向类员函数的指针,可以实现更加隐蔽的接口。

类函数指针与普通函数指针一样,也可以做函数参数,形成函数回调的效果,实现更加d性和通用的代码。

https://blogcsdnnet/yyx112358/article/details/78515420

-End-

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/12175290.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-21
下一篇2023-05-21

发表评论

登录后才能评论

评论列表(0条)

    保存