[2016-05-13][C++若干问题]

有错请指出,有错请指出,有错请指出,有错请指出,有错请指出,有错请指出,

下面的结论都是在VS下测试的,也许其他编译器会出现不同情况,

  • 比如下面这句,在VS下不能编译,但是在其他编译器能编译(华工OJ支持这种写法)

    1. int n = 5;
    2. int a[n];

1. 关于复制构造函数的某个特殊情况,

  1. A g(){ return A();}
  2. A c = g();
  • 这种情况,复制构造函数只调用了一次,实际上并没有创建匿名对象,匿名对象直接变成了声明的c,
  1. A c;
  2. c = g();
  • 如果是普通的赋值语句,那么它会先调用赋值构造函数来创建匿名对象,在调用”=”重载来进行赋值
  1. g();
  • 这个情况就会创建匿名对象,但是在函数结束之和,就会销毁(调用~A());
  1. "测试用代码"
  2. #include<iostream>
  3. using namespace std;
  4. class A{
  5. public:
  6. int a;
  7. A(int c = 0):a(c){
  8. cout<<"**********In A()\n";
  9. cout<<this<<"\n";
  10. cout<<"A:Constructor\n";
  11. cout<<"******Out A()\n";
  12. }
  13. A(A & b){
  14. cout<<"**********In Copy_A()\n";
  15. cout<< & b <<" to "<<this<<"\n";
  16. cout<<"B:Copy_Constructor\n";
  17. a = b.a;
  18. cout<<"**********Out copy_A()\n";
  19. }
  20. ~A(){
  21. cout<<this<<"~A\n";
  22. }
  23. A operator = (const A & b){
  24. cout<<"Operator =\n";
  25. a = b.a;
  26. return *this;
  27. }
  28. };
  29. A g(){
  30. cout<<"In g()\n";
  31. A c;
  32. cout<<"before g() return\n";
  33. return c;
  34. }
  35. int main(){
  36. //A c = g();
  37. A c;
  38. c = g();
  39. cout<<"C is:"<<&c<<"\n";
  40. //g();
  41. return 0;
  42. }

2. [2016-04-23][使用复制构造函数的时候,为什么没有调用构造函数来构造临时对象]

就是在

  1. Array operatpr +
  2. return tmp;//Array的某变量

中返回一个对象

然后中途会进入到tmp拷贝到临时对象的复制构造函数中,但是在这个函数里面使用this查看变量,发现this的元素没有初始化,也就是没有调用构造函数(不管是默认的还是复制的)!!!

解决办法:在构造函数里面调用一次构造函数.

3.关于构造函数的调用顺序

  • 基类构造函数 —> 成员对象的构造函数 —> 派生类的构造函数

4.关于符号重载的若干问题

  • “=”重载,”=”只能重载为非静态成员函数
  • 支持友元函数重载的必要性
    1. class qhy;
    2. qhy a,b;
    3. a = a + b;//(1)
    4. a = b + 1;//(2)
    5. a = 1 + b;//(3)
    • 上面 “+” 重载,假设是成员函数的重载,
    • 对于(1)来说,只要有参数为qhy的重载,就合法
    • 对于(2)来说,只要qhy有参数含int的构造函数,或者是参数为int的”+”重载,就合法
    • 对于(3)来说,无论qhy有什么东西,都是非法的,因为 1 + b调用的是 int类型(1的类型) 对于”+”的重载,显然系统自带的类型,没有参数是qhy类型的”+”重载
    • 为了解决上面(3)的情况,就需要使用友元函数重载 “+” 号,这样,只要”+”一边有qhy类型,就一定调用qhy里面”+”的友元重载
    • 一些习惯
  • 运算符操作需要修改对象,用成员函数重载
  • 运算符操作数希望有隐式转换,使用友元重载
  • 不能用友元重载的符号
    • = () [] ->
  • 必须友元
    • >>  <<

5.关于类中的静态成员

  • 只有静态常量整型数据成员才可以在类中初始化

    1. class qhy{
    2. static int a = 0; // 非法!
    3. static const int b = 0; //合法!
    4. };
  • 非常量静态成员初始化和普通变量的初始化一样,并且在类外初始化

6.类中的非静态常量,要在构造函数中初始化,并且只能使用初始列表初始化

  • 普通成员
  1. class qhy{
  2. public:
  3. const int a;
  4. qhy(int _a):a(_a){}//合法!!
  5. qhy(int _a){a = _a;}//非法
  6. };
  • 数组成员
  1. class qhy{
  2. public:
  3. const int a[2];//这个没办法初始化,还是使用静态成员数组吧
  4. static const int b[2] = {1,2};//非法!!,正确姿势请看c
  5. static const int c[2] ;
  6. };
  7. const int qhy::c[2] = {1,2};

7.关于类型转换

  • 可以通过构造函数实现类型的转换,就比如上面的”+”重载,假设重载参数类型只有qhy,但是调用的时候,其中一个参数不是qhy,假设是int,这个时候会看构造函数是否有int的重载版本,有就调用它,把int转换成qhy
  • 类型转换函数
    1. ClassX::operator Type(){
    2. //do something
    3. return Type_Value;
    4. }
  • 例子
    1. class qhy{
    2. public:
    3. int a;
    4. operator int(){return a;}
    5. };
    6. int main(){
    7. qhy a;a.a = 10;
    8. cout<<int(a);
    9. }

8.类中重名成员与函数

  • 重名成员

    1. class Base{
    2. public:
    3. int a;
    4. Base():a(0){}
    5. };
    6. class qhy : public Base{
    7. public:
    8. int a;
    9. qhy():a(1){}
    10. };
    11. int main(){
    12. qhy a;
    13. cout<<a.a<<" "<<a.Base::a<<"\n";
    14. //1 0
    15. }
  • 重名函数
    • 用法和上面类似

9.多重继承:一个类可以继承多个类

10.虚继承:若多个基类来个同一个基类,希望只继承一次,就是用虚继承

  • 非虚继承,调用了两次B的构造函数

  • 虚继承,调用了一次B的构造函数

    • 声明,继承前面加上virtual

      1. class qhy :virtual public Base{};
    • 虚继承的最高级的基类,就是上面的B,在D的构造函数中提供参数,不受B1,B2构造函数的影响

11.基类的初始化

  • 在构造函数初始化列表提供初始化参数,变量名变成基类镜子
  1. class qhy :public Base{
  2. qhy(int a):Base(a){};
  3. };
  • 继承基类的顺序决定了构造的顺序
  1. class qhy :public Base1,public Base2{};//先调用Base1的构造函数,在调用Base2的构造函数

12.使用指针引用派生类

  • 可以正常访问基类成员
  • 必须强制转换成派生类指针后,才能访问派生类的成员

13.使用派生类指针引用基类对象

  • 必须强制转换成基类指针之后,才能访问到基类对象

    小结:根据指针类型调用指针类型对应的函数,强制转换相当于加上了作用域符::

    1. class Base{
    2. public:
    3. int a,b;
    4. Base():a(0),b(1){}
    5. };
    6. class qhy:public Base{
    7. public:
    8. int b,c;
    9. qhy():b(2),c(3){}
    10. };
    11. int main(){
    12. qhy *pq;Base *pb;
    13. qhy q;Base b;
    14. cout<<b.a<<" "<<b.b<<" "<<q.b<<" "<<q.c<<"\n";//0 1 2 3
    15. pb = &q;//使用基类指针引用派生类
    16. cout<<pb->a<<" "<<pb->b<<"\n";//0 1
    17. //cout<<pb->c<<"\n";//错误,在Base中c不存在
    18. cout<<((qhy*)pb)->a<<" "<<((qhy*)pb)->b<<" "<<((qhy*)pb)->c<<"\n";//0 2 3,b访问到的是qhy的b
    19. //使用派生指针引用基类
    20. //pq = &b;//错误,类型不对
    21. pq = (qhy*)&b;
    22. cout<<pq->b<<pq->c;//乱码,因为b,c不存在
    23. return 0;
    24. }

14.虚函数

  • 上面,如果想用基类指针调用派生类对应的函数,每次都要强制转换一下,好麻烦,解决办法:使用虚函数

    • 即声明成虚函数之后,不再受到指针类型的影响,直接调用本身的函数
  • 虚函数的作用:使用基类指针引用派生类对象时,直接调用派生类对象对应版本的函数
  • 声明方法,在函数声明前面加上 virtual
  • 纯虚函数:只有声明没有定义的函数,(需要在派生类中定义,否则不能实例化)

    1. virtual int func() = 0;
    • 抽象类:含有纯虚函数的类
  • 虚析构函数:如果是动态创建的对象,并且使用基类指针来引用的话,delete的时候,调用的是基类的析构函数,如果希望调用派生类对应的析构函数,就把析构函数声明为虚函数

15.public,private,protected属性

  • 类成员的属性:

    • private:成员只能在类内部和友元内访问,子类和外部都不能访问
    • protected:类内部,友元,子类都可访问,类外部不能访问
    • public:谁都可以乱搞
  • 类的继承方式
- 基类成员属性 public protected private
继承类型 ↓继承之后的属性,属性性质→ 所有都可见 类内部,友元,子类可见 类内部,友元可见,子类不可见
public 完全不变 public protected private
protected public变成protectd,其他保持 protected protected private
private 全部变成private private private private

来自为知笔记(Wiz)

时间: 2024-11-13 12:30:21

[2016-05-13][C++若干问题]的相关文章

2016.05.13初识HTML5-02

第二天~早上8点上课,12点放学,1点又继续上课...真是压缩的实实在在的5天啊,就像吃压缩饼干不喝水一样.哈哈,不过我觉得明天会更累..因为后天是周天,我要去软件培训,学习Android开发,生产实习估计是逃定了.结果导员告诉我:你后天可以不来,但是你要后天之前把作品先提交上来.哇...我比别人少学一天,还要早交一天作品.不过为了去培训,我也是拼了..今天还是继续学习标签,规范网页的布局格式. 1.超级链接:语法<a href="将要跳转的网址">点击处该链接显示的标签名

9x25 LED 驱动框架分析 2016.07.13

进入内核 make menuconfig 输入 /led 回车搜索到 │ Location: │ │ -> Device Drivers │ │ -> LED Support (NEW_LEDS [=y]) 进入LED Support发现有这一项 []LED Support for GPIO connected LEDs 在内核搜索该字符串 grep "LED Support for GPIO connected LEDs" * -nR 搜索到 drivers/leds/K

2016.05互金平台移动端影响力50强榜单报告!

(文章来源:盈灿咨询) 6月21日下午,盈灿咨询在京举办互金平台移动端影响力报告暨2015网贷蓝皮书出版发布会,首次独家发布了<互金平台移动端影响力榜单TOP50>,北京大学汇丰商学院中小企业研究中心执行主任王家卓.网贷之家首席研究员&盈灿咨询总经理马骏.盈灿咨询副总经理于百程.爱钱进CEO杨帆等嘉宾出席了本次活动并做主题分享. 据悉,该报告选取了300余家互金平台5月的移动端数据,以平台在移动端的推广目的和移动互联网特点为支点,以指标.评分.分析为撬棍,展示了目前行业内互金平台的移动

微软Azure云之企业Exchange 2016部署13&mdash;DNS配置

本节我们来配置DNS域名解析. 因为本次Exchange部署在Azure公有云上,所有用户访问通过公网来进行连接,所以这里主要是公网DNS配置. 1.DNS正向解析 对于Exchange来说.如果邮件客户端仅仅使用MAPI模式连接,则需要配置mail.autodiscover.解析以及主域名的MX记录解析.如果需要其他如POP.SMTP.IMAP等服务时,有时为了区分服务DNS解析,也可以分别配置. 另外,这里设置了一条TXT解析:v=spf1 ip4: 13.78.59.202/32 –all

2016/05/04(反射)

反射:重点----每天都用反射,但是每天都不写反射     Java的反射技术是java程序的特征之一,它允许运行中的Java程序对自身进行检查,或者说“自审”,并能直接操作程序的内部属性. 使用反射可以获得Java类中各个成员的名称并显示出来.简单的说,反射就是让你可以通过名称来得到对象(类,属性,方法)的技术. 反射的作用? 可以通过反射机制发现对象的类型,发现类型的方法/属性/构造器? 可以创建对象并访问任意对象方法和属性等 主要点:运行时探究和使用编译时未知的类 Dog d1 = new

python学习2016.4.13

Python函数   (1)数据框的另一种定义方式,将数据内容(多维数组)直接放入data中,再定义columns和index.(数据框.columns是取列名,.index是取行名,取出的类型类似元组,可以用[0],[1]-直接取出) df = pd.DataFrame(data=[[34, 'null', 'mark'], [22, 'null','mark'], [34, 'null', 'mark']], columns=['id', 'temp', 'name'], index=[1,

2016.6.13 考试总结

一.哲哲回家 [题目描述]: 哲哲放学了,准备坐公交车回家.因为急着回家看MSN战士,所以他想用最短的时间回家,但是因为学校离家里比较远,有时候他需要转几趟车才可以回家.等车是需要一段时间的,而且每辆公交车的速度不一样,哲哲晕掉了,不知道怎样才可以在最短的时间里回家,作为一名cjoier,你应该帮帮他. 现在一直哲哲所在的城市有N个公交站点(学校在一号站点,哲哲家在N号站点)和M条公交线路,每条公交线路是一个有序集合,公交线路i包含Pi个站点a[i,1],a[i,2]…a[i,Pi],表示i号公

2016.05.20-2016.05.26这周工作时间和内容

这周的学习内容:这周学习了NS图和PAD图,流程图由一些特定意义的图形.流程线及简要的文字说明构成,它能清晰明确地表示程序的运行过程.在使用过程中,人们发现流程线不一定是必需的,为此,人们设计了一种新的流程图,它把整个程序写在一个大框图内,这个大框图由若干个小的基本框图构成,这种流程图简称N-S图.NS图形象直观,具有良好的可见度.例如循环的范围.条件语句的范围都是一目了然的,所以容易理解设计意图,为编程.复查.选择测试用例.维护都带来了方便:NS图简单.易学易用,可用于软件教育和其他方面:功能

【13】2016.12.13 周二--《小结2016》

本文地址 原文地址:简书 时间匆匆,年轮又一年,春夏秋冬走过,是时候盘点一下了,喜怒哀乐一年.整理后重新上路. 16年总体而言还是挺有收获和成长的.于工作,是技术更牢固了,书也读了不少.于情感,自然更是质的突破,毕竟有了女友,爱情甜如蜜吧.于其他,则亦有愈加肥胖之身躯,情感的受挫,同事的离去等. 15年过年春节,在家也是很珍惜的,每天拍照文字记录生活,还是要来上班的.记得那时的三人行,seo整天和八戒·亚当斯他们厮混在一起.倒也惬意.也终于从我大西二旗搬到了大朝阳的传媒大学.别了,我的Yello

2016.10.13 工作遇到的一些mongo问题

一.tokumx 2.4 用户管理操作 db.isMaster() use admin db.addUser("root","rootpwd")默认为管理员用户 db.auth("root","rootpwd")   验证用户 db.system.users.find()    查看用户 db.system.users.update({"user":"zayhuroot"},{"