7.8随笔(C++复习)

本文深入探讨C++中的高级概念,包括引用作为函数返回值的使用,register类型的限制及过时原因,类成员初始化的方法,常成员函数的特性和应用,虚继承解决二义性问题,以及运算符重载的实现技巧。

明天期末考试,稍微复习(预习)一下C++课程设计

把引用作为函数返回值:

#include <bits/stdc++.h>
using namespace std;

int a[10] = {1, 2, 3, 4, 5};

int &change(int i)
{
    return a[i];
}

int main()
{
    change(0) = 6;
    change(1) = 7;
    for (int i = 0; i < 5; i++)
        cout << a[i] << endl;
}

/*
Output:
6
7
3
4
5
*/

register类型:Register修饰符暗示编译程序相应的变量将将被频繁使用,如果可能的话,应将其保存在CPU的寄存器中,以指加快其存取速度。但是,使用register修饰符有几点限制:
(1)只有局部自动变量和形式参数可以作为寄存器变量,其他(如全局变量)不行。
(2)一个计算机系统中的寄存器数目是有限的,不能定义任意多个寄存器变量。
(3)局部静态变量不能定义为寄存器变量。
其实这个变量已经过时,因为现在的计算机处理速度够快,所以很少使用.。


C++类中的数据成员不可以直接赋初值,也就是定义的时候不能被初始化,而应该在构造函数中初始化(虽然C++11可以这么做)


类A将其它类对象作为成员,则建立A类对象时,成员(其他类)构造函数先执行

派生类不能继承基类的构造函数、析构函数、拷贝构造函数、拷贝赋值函数(重载运算符)


常成员函数:在普通的成员函数基础上使用const关键字进行修饰,定义与声明时都需要加

常成员函数无法对成员变量进行修改,但是可以调用类中的其他常成员函数

常量对象只能调用常成员函数,因为常量对象不能改变成员变量,而常成员函数保证了不对成员变量进行修改

#include <bits/stdc++.h>
using namespace std;

class A
{
public:
    int a;
    void f() const;
    void f2() const;
};

void A::f() const
{
    cout << "hello world\n";
    f2(); //调用类中的其他常成员函数
}
void A::f2() const
{
    cout << "hello world*\n";
}
int main()
{
    A temp2;
    const A temp = temp2; //常量对象
    temp.f();             //常量对象只能调用常成员函数,因为常量对象不能改变成员变量,而常成员函数无法对成员变量进行修改
    return 0;
}

虚继承与二义性
一般来说,在两种情况下会出现二义性问题

  1. 存在类A,类B,AB类存在同名成员x,AB作为基类继承得到C类时,C类会继承两个同名成员,这种情况可以用::作用域运算符解决
  2. 见下面示例。存在类A,类A单继承得到B1,B2,B1,B2多继承得到C,C会继承两份A的成员。
#include <bits/stdc++.h>
using namespace std;

class A
{
public:
    string name = "hesor";
};
class B1 : public A
{
};
class B2 : public A
{
};

class C : public B1, public B2
{
};

int main()
{

    C temp;
    cout << temp.a << endl;
    return 0;
}

这时候仍然可以使用作用域运算符解决,但是作用域运算符要放在B1,B2前面。

#include <bits/stdc++.h>
using namespace std;

class A
{
public:
    string name = "hesor";
};
class B1 : public A
{
};
class B2 : public A
{
};

class C : public B1, public B2
{
};

int main()
{

    C temp;
    cout << temp.B1::name << endl; //使用作用域运算符
    cout << temp.B2::name << endl;
    return 0;
}

不过显然,同是A中的成员,多份没有意义,这时候就用到了虚继承。
虚继承,在继承方式前面加上virtual关键字修饰,并且在每一个继承分支中都不能省略。

#include <bits/stdc++.h>
using namespace std;

class A
{
public:
    string name = "hesor";
};
class B1 : virtual public A //每一个继承分支都需要加关键字virtua;
{
};
class B2 : virtual public A //每一个继承分支都需要加关键字virtua;
{
};

class C : public B1, public B2
{
};

int main()
{

    C temp;
    cout << temp.name << endl;
    return 0;
}

重载类中的运算符
我们可以用两种函数重载运算符

  1. 类成员函数重载运算符(使用this指针)
  2. 非成员函数重载运算符
#include <bits/stdc++.h>
using namespace std;

class A
{
public:
    A()
    {
    }
    A(string a, int b)
    {
        this->name = a;
        this->score = b;
    }
    string name;
    int score;

    A operator+(A temp) //成员函数重载+运算符
    {
        A tempa;
        tempa.score = this->score + temp.score;
        tempa.name = this->name + temp.name;
        return tempa;
    }
};
bool operator==(A temp1, A temp2) //非成员函数重载==运算符
{
    if (temp1.score == temp2.score && temp1.name == temp2.name)
        return true;
    return false;
}
int main()
{
    A a("abc", 100);
    A b("abc", 333);
    A temp = a + b;
    cout << temp.score << ' ' << temp.name << endl;
    cout << (a == b ? "=" : "!=") << endl;
    return 0;
}
参考资料
  1. 数据存储类型:auto、static、register、extern
  2. C++类成员和数据成员初始化总结
  3. 关于C++ 类中数据成员在定义时初始化问题
  4. C++常对象和常成员函数详解
  5. C++ 重载运算符和重载函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hesorchen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值