C++学习笔记二

7、类的定义格式(续)
  >在类体中不允许对所定义的数据成员进行初始化:
   class TDate
   {
         public:
      ....
  private:
    int year(1998),month(4),day(9);
   };
  >类中的数据成员的类型可以是任意的:
   1.包括整型、浮点型、数组、指针和引用等;
   2.另一个类的对象,可以作为类的成员;
   3.自身类的对象不可以作为该类的成员;
   4.自身类的指针或引用可以作为该类的成员;
   5.当另一个类的对象作为该类的成员时,如果另一个类的定义在后,需要提前说明;
   6.一般在类体内先说明用户感兴趣的公有成员,再说明私有成员;
   7.习惯将类定义的说明部分或整个定义部分(包含实现部分)放到一个头文件;
 
8、构造函数和析构函数:
  》特殊的成员函数
  》构造函数:在创建对象时,使用特定的值来将对象初始化;
  》析构函数:用来释放对象,在对象删除前做一些清理工作;


9、拷贝初始化构造函数的三种情况:
a.明确表示由一个对象初始化另一个对象时;
例如:TPoint N(M);
b.当对象作为函数实参传递给函数形参时(传值调用);
例如:P=f(N);
c.当对象作为函数返回值时(数据值);
例如:return R;
#include<iostream.h>
#include"tpoint.h"
TPoint f(TPoint Q);
void main()
{
TPoint M(20,35),P(0,0);
TPoint N(M);     //1.M参数传递给N时会打印出Copy_initialization Constructor called
P = f(N);  
cout<<"P="<<P.Xcoord()<<","<<P.Ycoord()<<endl;//6.
 //6.同时由于M对象的释放,将打印Destructor called.
 //7.同时由于P对象的释放,将打印Destructor called.
     //8.同时由于N对象的释放,将打印Destructor called.
}
TPoint f(TPoint Q)   //2.N参数传递给Q时会打印出Copy_initialization Constructor called
{                      
cout<<"OK!"<<endl;//3.
int x,y;
x = Q.Xcoord() + 10;
y = Q.Ycoord() + 20;
TPoint R(x,y);
return R;         //4.R参数传递给P时会打印出Copy_initialization Constructor called
 //5.同时由于Q对象的释放,将打印Destructor called.
 //6.同时由于R对象的释放,将打印Destructor called.
 //7.匿名对象
}
/*
输出:
Copy_initialization Constructor called.
  Copy_initialization Constructor called.
  OK!
  Copy_initialization Constructor called.
  Destructor called.
  Destructor called.
  Destructor called.  //匿名对象
  P=30,55
  Destructor called.
  Destructor called.
  Destructor called.
*/


10、赋值的构造:
Location &operator = (Location &p);   //Location(Location &p)


Location & Location::operator = (Location& p)
{
X = p.X;
Y = p.Y;
cout<<"Asignment operator called."<<endl;
return *this;  //返回this指针
}


补充:
当类中声明有指针数据成员时,必须定义拷贝初始化和赋值操作,否则编译器生成的
拷贝初始化操作和赋值操作的执行将导致程序在运行时产生问题;
class A        A::A(int i)
 {            {
 public:             p=new int(i);
  A(int i);         }
  ~A();          A::~A()
 private:        {
  int *p;             delete p;
 };           }
void main()
{
A a(5);
A b(a);    //运行过程中将会出现问题。原因在于b也有变量将指向5,释放将进行两个
  //因此赋值操作要谨慎,特别出现了指针成员时,复制函数要另外书写。
A c(5),d(10);
d = c;         //函数参数赋值 和 等式赋值一样将会造成两个指针指向同一个地方。


};


上述的程序明显不对,修改后有:
#include<iostream.h>
class A {
public:
A(int i); //构造函数
A(A &r);    //重载构造函数
~A() ; //析构函数
A &operator=(A &r);  //拷贝初始化构造函数中,传递的参数必须是类引用。
private:
int *p ;
};
//构造函数
A::A(int i)

this->p = new int(i);  //给*p赋初始值
}
//拷贝初始化构造函数
A::A(A&r)              //要使用别的A类的成员对另一个赋值,必须使用指针或引用!!!!
{
p = new int(*r.p);  //1、new int(int i);  注意引用中的成员使用.(成员)来获取。
}
//析构函数
A::~A()
{
delete p; 
}
//赋值操作函数
A & A::operator = (A &r)
{
if(this == &r)          //如果r和this地址不同,那么返回this.
return *this;
cout<<"I am Here!!!!!!!!!"<<endl;
*p = *r.p; //2、引用要取出成员用.(成员)
return *this; //3、如果要将引用中指针成员取出,必须要将*加载*r.p前面
//   而不是r.(*p)。
}
void main()
{
A a(5);
A b(a);    //运行过程中将会出现问题。原因在于b也有变量将指向5,释放将进行两个
  //因此赋值操作要谨慎,特别出现了指针成员时,复制函数要另外书写。


A c(6),d(10);  //重写与缺省:如果d不进行初值赋值,可能会出现构造函数重写的重叠,导致出错!!
d = c;         //函数参数赋值 和 等式赋值一样将会造成两个指针指向同一个地方。
};
总结:1、new int(int i);  注意引用中的成员使用.(成员)来获取。      
      2、this指针取出成员用this->p,即->。
      3、如果要将引用中指针成员取出,必须要将*加载*r.p前面而不是r.(*p)。
      4、注意:
             (1)A::A(A&r)该函数为拷贝初始化构造函数,实参参数为A &类型,在三种情况下调用:
         a.明确表示由一个对象初始化另一个对象时;
例如:TPoint N(M);
b.当对象作为函数实参传递给函数形参时(传值调用);
例如:P=f(N);
c.当对象作为函数返回值时(数据值);
例如:return R;
             (2)A & A::operator=(A &r)为赋值操作函数,实参和返回值为A &类型。
           
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值