C++学习笔记

c++类的学习笔记;
类中所有对象都有自己的存储空间,但是,方法由所有对象共享,即方法只有一个副本
例如:有一个类 class Stock{};
Stock acce,bcce;
类有一个方法叫void show(int ,double,...){//...}
类中定义了成员变量 int a;double c;
acce.show() ,与 bcce.show()占据同一块内存。
acce.a 与 bcce.a 占据不同的内存。


  类在实现构造函数的同时,也会存在一个析构函数{Stock && ~Stock}
  构造函数默认为无参数的 Stock();并可以省略。
  但是,当存在多个构造函数时,默认构造函数,即不含参数的构造函数不可省略。否则编译器会警告。
  
  建议采用初始化的方式设置对象的值,而不是采用赋值的方式:
  Stock stock1 = Stock(x,y,z,...);//初始化
  Stock stock2;stock2 = Stock(x,y,z,...);//赋值
  
  当然如果是C++11,可以采用大括号赋值 即 Stock stock1 {x,y,z,...}; Stock stock2 = {x,y,z,...};
  
  注意有一种设置方式:Stock stock3 = 55;//设置value。这是尽量要避免的
  
  this 指针可以指代当前操作对象,而不必特地传入一个指针来指向本身(作用于调用自身成员函数时使用)
  比如copy时
  Stock& Stock::copy_a(const Stock& rhs)
  {
    if(this != &rhs)//如果要赋值的对象与自己不相等,则
{
  x = rhs.x;
  y = rhs.y;
  //...

}
return *this;//返回本身的副本
  }
  注:每个成员函数都拥有一个this指针,指向调用对象。
  
  C++11 中设置了一种新的枚举方式来解决枚举名冲突的问题
  enum class egg{Small,Large,Jumbo};//可以使用struct替换class
  enum class Tshirt{Small.Large,Jumbo};
  这样就形成一种作用域类型的枚举,防止常量冲突。 使用时附带作用域名:
  egg::Small;  Tshirt::Small;
  但是却不能隐式的转换为整形,需要时需要显式转换 int(egg::Small);
  非作用域的枚举则可以隐式转换。
  
  在类设计时,对于函数返回的一个要点:
  在函数里创建临时变量,无论是简单类型还是,自己的类对象,都是属于临时变量,那么在返回的时候
  便不能返回它的引用或者他的指针,否则在返回后,该变量会被删除。导致返回值引用或者指向一个无效
  的变量,而返回它本身则会让程序在删除它之前创建一个它的拷贝,返回给调用,这样才能达到我们的预期。
  
  
  重载运算符:
  关键字是:operator
  使用方法:返回值 作用域::operator运算符(参数){ /*重载之后的功能*/ }
  运算符必须是C++里内置的而不能是自己定义的。
  重载运算符的操作数至少有一个是用户自己定义的类型,这是为了防止将内置的标准类型重置运算符。如将(1 + 1)变成(1 - 1)的功能;

  同样,也支持两个对象以上的重载操作,例如 重载“+” 用于Stock类的运算

Stock operator+(const Stock &t){Stock temp;temp.x = x + t.x;return temp;}

  上述式子转换为:

<pre name="code" class="cpp">Stock t1 = t2.operator+(t3.operator+(t4));

 

  得到我们预期的目的。    友元函数与运算符重载的运用。  我们看到,C++内置的标准类型通过 重载 << 运算符 可以由std::cout 任意输出,十分方便,我们自己定义的类型呢?当然可以:  首先,为了不破环iostream文件内容,采用在自己的类中使用友元函数来实现这个功能:  声明时,在类中声明,带上friend关键字在最前方。  定义时,不带friend关键字。   friend std::ostream operator<<(std::ostream &os,const Stock &t);//声明
  std::ostream & operator<<(std::ostream &os,const Stock &t){
    os << t.x << t.y ....;return os;
  }//定义,伪代码。
 
 记得定义时不带作用域运算符。
  
  重载运算符时候会遇到一个问题,即选择成员函数,还是非成员函数
  具体来说,还是举个例子。

  重载一个“*”运算符,使之能作用于类Stock。

Stock operator+(const Stock &t){Stock temp;temp.x = x + t.x;return temp;}

 Stock st1,st2;
  st1 += st2;//成功,这就是所谓的成员函数现象 ==>st1 = st1.operator+(st2);
  st1 = 2*st2;//这就完蛋了,因为2,不是Stock类,不能调用这个operator+函数啊!怎么办?这就是非成员函数的作用,友元来了  
  //friend Stock operator*(const Stock &s1,const Stock &s2 ){Stock temp;temp.x = s1.x + s2.x;return temp;} 这就可以啦。
  //用这句话替换上面那句话,这就可以啦。
 

这个相比之下,非成员函数和成员函数的差别就在于,参数的传递,非成员函数使用比成员函数多一个参数,原因在于,成员函数使用this指针
  隐形传递参数。
  
  当重载运算符所作的运算过多时,那么可以考虑使用构造函数来帮助你实现你的目的,相当于新建一个新的对象并且赋值给调用对象。
  例如,举个栗子:
  我们有一个类Rectangle 其中包含有属性,长,宽,面积,(x,y,area).
  area 通过成员函数 set_area() 来设置,那么如果我们要让两个长方形的长和宽相加,并得到新的长方形的面积,我们如果用常规的方法,循规蹈矩的
  十分麻烦,而我们可以通过设置构造函数Rectangle(double n1,double n2){x = n1;y = n2;set_area();}来一步实现
  即 Rectangle operator+(const Rectangle &R){return Rectangle(x+R.x,y+R.y);}
  
  
  
  
  
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值