类&对象(二)

关于数据成员:

1.静态数据成员:属于类而不属于对象

class Spreadsheet
{
private:
    static int counter;
};
int Spreadsheet::counter=1;
需要在类外进行声明,初始化(未初始化会初始化成0或者nullptr)

2.常量数据成员/静态常量数据成员const static

3.引用数据成员

4.常量引用数据成员


关于方法:

1.静态方法:应用于全部类对象,没有this指针,和普通函数一样,不会访问特定对象的数据成员(但是可以访问类的静态数据成员)

2.const方法(原理:将方法内用到的数据成员都标记为const引用):末尾加const,不改变任何数据成员,如:double getValue() const;

注意:这个const在进行定义的时候也需要加。

(可以将数据设置为mutable,那么const方法可以进行修改)

3.可以利用const进行方法的重载(两个方法的名称相同,参数个数类型也相同,但是一个是const方法,一个不是)

4.默认参数

形如:Spreadsheet(const Spreadsheet& dst,int inWidth=kMaxWidth,int inHeight=kMaxHeight);

所有参数都有默认值的就是默认构造函数,默认构造函数和所有参数都有默认值的构造函数不能并存;(用=delete)

5.内联方法:编译器将方法体或者函数体直接插到调用方法或者函数的位置;

使用inline关键字,内联比#define更安全


关于友元:只能声明另一个类、函数为本类的友元;不能将本类声明为另一个类的友元


运算符重载:

operator运算符   的形式,重载加法如下:

声明:SpreadsheetCell operator+(const SpreadsheetCell& cell) const;

函数体:

SpreadsheetCell SpreadsheetCell::operator+(const SpreadsheetCell& cell) const
{
    SpreadsheetCell newCell;
    newCell.setValue(mValue+cell.mValue);
    return newCell;
}


编程:

将数据成员设置为private,并提供修改和获取该值得方法,可以防止修改该值

接口只包含public方法,接口不应包含任何数据成员,为了保持稳定;


(1)this指针:指向对象的指针,用于访问数据成员或者调用方法;每个普通的方法都传递一个隐藏的this指针,可以用来访问数据成员,也可以用来消除名称歧义;

只能在成员函数中使用,全局函数和静态函数都不能使用this;

this指针并不占用对象的空间;占用参数传递的栈空间或者是寄存器的空间;

成员函数执行前创建,成员函数执行结束后删除; 

(2) noexcept关键字

voidFunc3() noexcept;
noexcept的功能相当于throw(),表示该函数或方法不会抛出异常。如果noexcept修饰的函数抛出了异常,编译器可以选择直接调用std::terminate()终止程序运行。noexcept比throw()效率高一些

(3)重载不能只修改返回值类型,必须有参数不同

(4)尽量在构造函数中使用初始化器;

(5)静态类、静态成员函数、静态成员变量

静态类:类的声明前面带一个static,只能包含静态成员类型,不能进行实例化;不能有接口,不能有任何public

静态成员函数:没有this指针,不能对对象的普通成员变量进行访问;

静态成员变量:类域的全局变量。初始化不能放在头文件中,类外进行初始化;被类的对象以及派生类的对象所共享;

普通静态函数:函数默认是extern的,其他的文件可用;将一个函数声明成static,就可以防止命名冲突,并且不能被其他文件所用;生命周期为整个程序的运行阶段,在静态存储区中,调用的速度会快于普通函数(因为普通函数有压栈的操作);

(6)构造函数的初始化列表中,成员变量的初始化顺序只与它们在类中的声明顺序有关,而与初始化列表中的顺序无关;

尽量不要用一个成员变量初始化另一个成员变量;

(7)如果有任意一个构造函数已存在,就不会生成默认构造函数,这个时候classtype a;这种声明语法是错的;

(8)C++类编译之后,自动生成的有:默认构造函数(=default没有任何实参的构造函数,并且仅仅在没有定义构造函数的时候生成)、拷贝构造函数(即使定义了其他的构造函数,也会生成,并且参数为const引用),copy assignment操作符析构函数,并且都是public和inline

(9)为了驳回编译器自动提供的功能(如拷贝构造),可以将相应的成员函数声明为private并且不予实现。

(10)在编写operator=运算符重载的时候,①return *this,②处理自赋值的情况(即判断参数 == *this)

(11)成员函数和非成员函数的选择:

尽量选择非成员函数,这样可以增加封装性以及包裹弹性。(封装性的衡量标准是有多少函数可以直接访问成员变量,加一个成员函数,封装性就会降低)

需要进行隐式类型转换的时候,函数必须是非成员函数。

(12)声明为explicit的构造函数不能在隐式转换中被调用,只能进行显式调用。

class A {

public:

explicit A(int i)

{

val = i;

}

private:

int val;

}

A a1 = 12;  //隐式调用构造函数出错

A a1(12); //只能进行显式调用

但是可以使用static_cast<A> 12进行转换


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值