类的设计

一、编译器生成的成员函数

1、默认构造函数:默认构造函数要么没有参数,要么所有的参数都有默认值,如果没有定义任何默认构造函数,编译器将定义默认构造函数。派生类构造函数的成员初始化列表中没有显示调用基类的构造函数,则编译器将使用基类的默认构造函数来构造派生类对象的基类部分,如果基类没有构造函数,将导致编译错误。如果定义了某种构造函数,编译器将不会定义默认构造函数,此时,默认构造函数必须自己提供。如果类包含指针成员,则必须初始化这些成员,最好提供一个显示默认构造函数,将所有的数据成员都初始化为合理的值。

2、复值构造函数:以下情况使用:1)将新对象初始化为一个同类对象;2)按值将对象传递给函数;3)函数按值返回对象;4)编译器生成临时对象。如果程序没有使用复制构造函数,编译器将提供原型,但不提供函数定义,否则程序将定义一个执行成员初始化的复制构造函数,

3、赋值构造函数:默认的赋值构造函数用于处理不同类对象之间的赋值,不要讲赋值于初始化混淆了。

二、其他的类方法

1、构造函数:构造函数不能被继承,构造函数在完成其工作之前,对象并不存在。

2、析构函数:一定要显示定义析构函数来释放构造函数使用new分配的内存,并完成类对象所需的任何特殊清理工作。对于基类,即使不需要析构函数,也应提供一个虚析构函数

3、转换:转换函数可以是没有参数的类成员函数,也可以是返回类型被声明为目标类型的类成员函数。即使没有声明返回类型,函数也应该返回所需的转换值。关键字explicit允许使用强制类型转换进行显式转换,但不允许进行隐式转换。如explicit star(const char *);(1)star north;north = “polaris”;不允许隐式转换。(2)north = star(“polaris)

4、按值传递对象与传递引用:编写使用对象作为参数的函数时,应按引用而不是按值来传递对象,这样提高效率。按值传递对象涉及到生成临时拷贝,即调用复制构造函数,然后调用析构函数。按引用传递对象的另一个原因是,在继承使用虚函数时,被定义为接受基类引用参数的函数可以接受派生类。

5、返回对象和返回引用:如果函数返回在函数中创建的临时对象,则不要使用返回引用,应该返回该对象的副本。如果函数返回的是通过引用或指针传递给它的对象,则应按引用返回对象。返回对象涉及生成返回对象的临时副本,从时间和效率上要低于返回引用。临时副本在函数结束后消失,这时必须返回函数对象。

6、使用const:使用const不改变参数、不改变调用它的对象。void star::show() const {}。这里的const表示const star *this。

const stock &stock::topval(const stock &s) const;第一个const修饰返回值,第二个const修饰引用s,第三个const修饰this指针。

三、共有继承的考虑因素

1、is-a关系:表示is-a关系的方式之一是无需进行显式类型转换,基类指针或引用可以指向派生类指针或引用。反过来却行不通。

2、什么不能被继承:构造函数不能被继承,创建派生类对象时,必须调用派生类的构造函数。而派生类构造函数通常使用成员初始化列表语法来调用基类构造函数,以创建派生类对象的基类部分。如果派生类对象没有在初始化列表中调用基类构造函数,将使用基类的默认构造函数。析构函数也是不能继承的。然而在释放对象时,程序首先调用派生类的构造函数,然后调用基类的构造函数,如果基类没有默认构造析构函数,编译器将为派生类生成默认析构函数,对于基类,其析构函数应该设置为虚的。赋值构造函数也是不能继承的,派生类继承的方法的特征标与基类完全相同,但赋值构造函数的特征标随类而异。

3、赋值构造函数:如果类构造函数使用new来初始化指针,则需要提供一个显式赋值运算符。必须给类的每个成员提供赋值运算符。如果使用派生类的引用或指针指向基类的引用或指针,则必须有一个转换构造函数,BrassPlus(const Brass &)如果有转换构造函数可以接受一个类型为基类的参数或其他参数,条件是其他参数有默认值。还可以定义一个将基类赋值给派生类的赋值构造函数。除以上两种情况外,只能使用显式强制类型转换。

4、私有成员与保护成员:对于派生类,保护成员类似于共有成员,对于外部而言,保护成员与私有成员类似。派生类可以直接访问基类的保护成员,但只能通过基类的成员函数来访问私有成员。

5、虚方法:如果希望派生类能够重新定义方法,则应在基类中将方法定义为虚的,这样可以启用动态联编。如果不希望重新定义方法,则不必将其声明为虚的。

6、析构函数:基类的析构函数是虚的,这样当通过指向对象的基类指针或引用来删除派生对象时,程序将首先调用派生类的析构函数,然后调用基类的析构函数,而不仅仅是调用基类的析构函数。

7、友元函数:友元函数非类成员,所以不能继承。派生类中的友元函数使用基类中的友元函数可以通过强制类型转换,将派生类引用或指针转换为基类引用或指针,然后使用转换后的指针或引用来调用基类的友元函数。

8、有关基类使用方法的说明:以公有方式派生的类的对象可以通过多种方式来使用基类的方法

(1)派生类对象自动使用继承而来的基类方法,前提是派生类没有重新定义该方法。

(2)派生类的构造函数自动调用基类的构造函数;

(3)派生类的构造函数自动调用基类的默认构造函数,如果没有在成员初始化列表中指定其他构造函数;

(4)派生类构造函数显式地调用成员初始化列表中指定的基类构造函数;

(5)派生类方法可以使用作用域解析运算符来调用公有的和受保护的基类方法;

(6)派生类的友元函数可以通过强制类型转换,将派生类引用或指针转换为基类的引用或指针,然后使用该指针或引用来调用基类的友元函数。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值