博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
3. 类
阅读量:7242 次
发布时间:2019-06-29

本文共 2381 字,大约阅读时间需要 7 分钟。

hot3.png

1.    在构造函数中完成工作

(1)仅完成成员变量的初始化,其他复杂的初始化由 Init() 函数完成。

(2)构造函数中不允许使用异常处理。

(3)如果构造函数是虚函数,则其调用不会传至子类,可能引起错误,访问未初始化的全局变量等问题。

2.    默认构造函数

(1)类定义了成员变量,而没有其他构造函数,则应该定义默认构造函数,在函数内对成员变量初始化。

(2)创建一个类对象,而不传入参数时,会调用默认构造函数。

(3)继承自其他类,且未增加成员变量的子类,不需要再定义默认构造函数。

3.    显式构造函数

(1)explicit 用于仅有一个参数的构造函数,可避免产生类型转换。

(2)只接受一个参数的构造函数可用于类型转换。如 Foo::Foo(string name),向以 Foo 类型为参数的函数传递 string 参数时,将调用这个构造函数完成 string 到 Foo 的转换。

(3)只有一个参数的构造函数,但不使用 explicit 的例外情况

a.    复制构造函数;

b.    打算作为透明封装的类;

(4)示例

class Foo{public:    // foo.Func(std::string("hello")); 编译错误,explicit 避免了类型转换,创建临时对象    explicit Foo(const std::string &name)    {    }        void Func(const Foo &foo)    {    }};

4.    复制构造函数

(1)限制编译器自动生成复制构造函数和赋值构造函数的方法。

方法一:

a.    宏定义

#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ TypeName(const TypeName&); \ void operator=(const TypeName&)

b.    作用

声明私有的复制构造函数和赋值构造函数,但不定义实现,可限制编译器自动生成,及外部的调用;

未定义实现,可在成员函数、友元函数调用时,产生连接错误;

c.    示例

class Foo{public:    Foo(void);    ~Foo(void);    private:    DISALLOW_COPY_AND_ASSIGN(Foo);};

方法二:

a.    示例

class CUncopyassign{private:    CUncopyassign(const CUncopyassign&);    CUncopyassign& operate= (const CUncopyassign&);};class Foo : public CUncopyassign{// 不再声明复制构造函数、赋值构造函数};

b.    作用

成员函数或友元函数拷贝 Foo 对象时,编译器生成复制构造函数、赋值构造函数,并调用基类的对应函数,这些函数是私有的,产生编译错误;

(2)利:复制构造函数方便对象的复制,将构造和复制进行了结合。

(3)弊:对象的显示复制常会导致缺陷和引起性能问题,降低代码的可读性。

(4)如果类需要复制性,提供复制方法,如 CopyForm() 或 Clone(),而不使用不能被显示调用的复制构造函数。

(5)复制方法不能满足要求(如保存在STL容器)时,可提供复制构造函数、赋值构造函数。

5.    结构体与类

(1)对象只是用来保存数据时,使用结构体,其他情况则使用类。

6.    继承

(1)组合通常比继承更合适。

(2)使用继承时,一般为公有继承。

(3)继承的两种方式:实现继承,实质性代码都被子类继承;接口继承,子类只继承接口名称;

(4)利:实现继承重用基类代码来减小程序规模。接口继承通过编程使一个类对外暴露特定的API。

(5)弊:实现继承,子类的实现代码需在基类和自身展开,理解这些实现变得困难,子类不能覆盖非虚方法。

(6)定义了虚函数的类,析构函数都应该被虚化。

(7)子类使用基类方法时,用 protected 加以限制。

(8)重写继承的虚函数时,在子类中显示声明其为 virtual。

7.    多重继承

(1)只有但仅一个基类被实现继承,而其他类都是纯接口,且以 interface 作为后缀声明时才允许多重继承。

8.    接口

(1)满足一下条件的类被称为纯接口

a.    只有公共的纯虚函数和静态方法;

b.    只有静态数据成员;

c.    没有构造函数定义,或声明为 protected 的默认构造函数;

d.    继承满足以上条件且以 interface 后缀结束的基类的子类;

9.    运算符重载

(1)利:像内建类型一样操作,代码更直观。

(2)弊:

a.    误以为大开销的操作,是小开销的内建操作;

b.    找到重载运算符的调用点比较困难;

c.    一些运算符也适用于指针,但容易造成程序缺陷;

d.    可能造成歧义;

(3)一般情况下,不重载运算符,尤其是赋值运算符。如果一个类需要被前置声明,应避免单目运算符 & 的重载。

10.    访问控制

(1)数据成员应该被定义成私有,静态数据成员除外。

11.    声明次序

(1)方位次序

a.    public;

b.    protected;

c.    private;

(2)成员次序

a.    类型定义(typedef)和枚举(enum);

b.   static、const 数据成员;

c.    构造函数;

d.    析构函数;

e.    类方法;

f.    数据成员;

12.    定义简短函数

(1)函数应该简短且功能单一。

(2)函数超过40行时,应注意考虑在不改变程序结构的情况下将其拆分。

转载于:https://my.oschina.net/u/2250495/blog/351661

你可能感兴趣的文章
kafka 文档 (一)
查看>>
zookeeper学习之zkclient事件监听<十>
查看>>
【笔记】如何做好一场技术演讲——观点烙刻
查看>>
Laravel学习一
查看>>
快速搭建discuz论坛系统
查看>>
java自定义实现数值的四舍五入
查看>>
解决windows中输入法图标丢失的方法
查看>>
我的友情链接
查看>>
TcpDump安装设置
查看>>
squid proxy server简单应用
查看>>
HA集群--corosync+pacemaker
查看>>
lduan server 2012活动目录关于站点复制与信任关系 (五)
查看>>
我的友情链接
查看>>
写一个函数,接受一个整数,输出这个整数的所有因子
查看>>
如何评审需求
查看>>
Java HashMap vs HashTable
查看>>
C# 抽象类与抽象方法
查看>>
oracle 视图
查看>>
【总结】kafka-topics.sh --describe显示结果解释
查看>>
windows 10中文用户名导致部分软件无法使用的解决方法
查看>>