C++学习笔记二

使用类

  1. 运算符重载

  • 重载后的运算符必须至少有一个操作数是用户定义的类型
  • 使用运算符时不能违反原来运算符的句法规则, 同样不能修改运算符的优先级
  • 不能创建新的运算符, 例如定义operator**()函数来表示求幂
  • 不能重载以下运算符
  • sizeof : sizeof运算符
  • . : 成员运算符
  • .* : 成员指针运算符
  • :: : 作用域解析运算符
  • ?: : 条件运算符
  • typeid : 一个RTTI运算符
  • const_cast, dynamic_cast, reinterpret_cast, static_cast : 强制类型转换运算符
  • 以下运算符只能通过成员函数重载
  • = : 赋值运算符
  • () : 函数调用运算符
  • [] : 下标运算符
    -> : 通过指针访问类成员的运算符
  • 以下运算符可通过成员函数或非成员函数重载


    reloadable_operator.png
  1. 友元

  • 友元有三种:
  • 友元函数
  • 友元类
  • 友元成员函数
    通过让函数成为类的友元,可以赋予该函数与类成员函数相同的访问权限
  • 为何需要友元

在为类重载二元运算符时, 常常需要友元
双目运算符交换两边操作数结果应该是一样的, 为了满足两种用法, 非成员函数重载运算符为了能够使用类的私有成员将函数声明为类的友元函数
创建友元函数的方法如下代码:

class Point {
    int x;
    int y;
public:
    Point(int xv = 0, int yv = 0): x(xv), y(yv) {}
    Point operator*(int fac) const {
        Point res;
        res.x = x * fac;
        res.y = y * fac;
        return res;
    }
    // 1. 将函数原型放在类声明中, 并加上关键字friend
    friend Point operator*(int fac, const Point& p);
    void show() {
        cout << "(" << x << ", " << y << ")\n";
    }
};
// 2. 编写定义函数, 他不是成员函数不要加Point::限定
//    另外注意不能在定义中使用friend关键字, 除非为内联函数的情况(原型也是定义)
Point operator*(int fac, const Point& p) {
    Point res;
    res.x = p.x * fac;
    res.y = p.y * fac;
    return res;
}
  • 常用的友元: 重载<<运算符

用cout << name 来输出用户定义类型
一种实现代码如下:

// 在类中声明原型
friend void operator<<(ostream & os, const Point& p);
// 定义
void operator<<(ostream & os, const Point& p) {
    os << "(" << p.x << ", " << p.y << ")\n";
}

另一种更好的实现, 适应cout << x << y这种用法
代码如下:

ostream & operator<<(ostream & os, const Point& p) {
    os << "(" << p.x << ", " << p.y << ")\n";
    return os;
}
  1. 类的自动类型转换和强制类型转换

  • C++的类型转换
  • 将一个标准类型变量的值赋给另一种标准类型的变量时, 如果这两种类型兼容, 则C++自动讲这个值转换为接收变量的类型
long a = 22; // type int -> type long
double b = 33; //
int c = 3.14; //
  • C++不自动转换不兼容的类型, 例如:
    int* p = 10;
  • 但是可以使用强制类型转换
    int* p = (int*)10;
  • 将构造函数用作自动类型转换
class ConvInt {
public:
    ConvInt(int x) { m_x = x; }    
private:
    int m_x;
}
ConvInt ci = 10; // 合法
  • explicit关键字用于关闭这种特性, 但仍可以显示转换
class ConvInt {
public:
    explicit ConvInt(int x) { m_x = x; }    
private:
    int m_x;
}
ConvInt ci = 10; // 不合法
ConvInt cj = ConvInt(10); // 合法
ConvInt ck = (ConvInt)10; // 合法
  • 注意: 只接收一个参数的构造函数定义了从参数类型到类类型的转换
  • 何时使用ConvInt(int)函数?

如果在声明中使用了关键字explicit, 则ConvInt(int)将只用于显示的强制转换, 否则还可以用于以下隐式转换:

  • 将ConvInt对象初始化为int值时
  • 将int值赋给ConvInt对象时
  • 将int值传递给接受ConvInt参数的函数时
  • 返回值被声明为ConvInt的函数试图返回int值时
  • 在上述任一种情况下,使用可转换为int类型的内置类型时
    对以上最后一条而言转换不能出现二义性
  • 转换函数

转换函数用于将类类型转换为某种类型
例如有以下语句

ConvInt ci(10);
double dt1 = double(ci);
double dt2 = (double)ci;
double dt3 = ci;

转换函数应满足以下几点:

  • 转换函数必须是类方法
  • 转换函数不能指定返回类型
  • 转换函数不能有参数
    例如, 转换为double类型的原型声明如下:
    operator double();
  • 程序中不能出现二义性转换, 例如:
class ConvInt {
public:
    ConvInt(int x) { m_x = x; }
    operator int() {
        return m_x;
    }
    operator double() {
        return double(m_x);
    }
private:
    int m_x;
}
ConvInt ci(1);
double dt = ci;  // 合法, 根据上下文知道使用operator double()转换
cout << ci;      // 不合法, 编译器会认为有二义性而拒绝
cout << int(ci); // 合法
  • 隐式自动转换请谨慎使用, 建议永远做显式转换
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容