c++基础分析(一)

2014-11-24 10:20:26 · 作者: · 浏览: 1

1、拷贝构造函数(深拷贝和浅拷贝)

拷贝构造函数的形式

复制代码代码如下:
Class A
{
public:
  A();
  A(const A&);//拷贝构造函数
} 拷贝构造参数是引用类型,其原因如下:当一个对象以传递值的方式传一个函数的时候,拷贝构造函数自动被调用来生成函数中的对象(符合拷贝构造函数调用的情况)。如果一个对象是被传入自己的拷贝构造函数,它的拷贝构造函数将会被调用来拷贝这个对象,这样复制才可以传入它自己的拷贝构造函数,这会导致无限循环直至栈溢出。

拷贝构造函数调用的三种形式:
1.一个对象作为函数参数,以值传递的方式传入函数体;
2.一个对象作为函数返回值,以值传递的方式从函数返回;
3.一个对象用于给另外一个对象进行初始化(常称为复制初始化)。
总结:当某对象是按值传递时(无论是作为函数参数,还是作为函数返回值),编译器都会先建立一个此对象的临时拷贝,而在建立该临时拷贝时就会调用类的拷贝构造函数。

深拷贝和浅拷贝
如果在类中没有显式地声明一个拷贝构造函数,那么,编译器将会自动生成一个默认的拷贝构造函数,该构造函数完成对象之间的浅拷贝。自定义拷贝构造函数是一种良好的编程风格,它可以阻止编译器形成默认的拷贝构造函数,提高源码效率。
在某些状况下,类内成员变量需要动态开辟堆内存,如果实行浅拷贝,也就是把对象里的值完全复制给另一个对象,如A=B。这时,如果B中有一个成员变量指针已经申请了内存,那A中的那个成员变量也指向同一块内存。这就出现了问题:当B把内存释放了(如:析构),这时A内的指针就是野指针了,出现运行错误。事实上这就要用到深拷贝了,要自定义拷贝构造函数。
深拷贝和浅拷贝可以简单理解为:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝。

深拷贝例子:

#include 
  
   
using namespace std;
class A{
public:
  A(int b,char* cstr){
    a=b;
     str=new char[b];
    strcpy(str,cstr);
  }
  A(const A& C){
    a=C.a;
    str=new char[a]; //深拷贝
    if(str!=0)
     strcpy(str,C.str);
  }
  void Show()  {
    cout<
    
    


2、 C++中的类成员声明static

在类中声明static变量或者函数时,初始化时使用作用域运算符来标明它所属类,因此,静态数据成员是类的成员,而不是对象的成员,这样就出现以下作用:

(1)类的静态成员函数是属于整个类而非类的对象,所以它没有this指针,这就导致 了它仅能访问类的静态数据和静态成员函数

(2)不能将静态成员函数定义为虚函数。

(3)由于静态成员声明于类中,操作于其外,所以对其取地址操作,就多少有些特殊 ,变量地址是指向其数据类型的指针 ,函数地址类型是一个“nonmember函数指针”。

(4)由于静态成员函数没有this指针,所以就差不多等同于nonmember函数,结果就 产生了一个意想不到的好处:成为一个callback函数,使得我们得以将C++和C-based X W indow系统结合,同时也成功的应用于线程函数身上。

(5)static并没有增加程序的时空开销,相反她还缩短了子类对父类静态成员的访问 时间,节省了子类的内存空间。

(6)静态数据成员在<定义或说明>时前面加关键字static。

(7)静态数据成员是静态存储的,所以必须对它进行初始化。 (程序员手动初始化,否则编译时一般不会报错,但是在Link时会报错误)

(8)静态成员初始化与一般数据成员初始化不同:

初始化在类体外进行,而前面不加static,以免与一般静态变量或对象相混淆;
初始化时不加该成员的访问权限控制符private,public等;
初始化时使用作用域运算符来标明它所属类;
所以我们得出静态数据成员初始化的格式:
<数据类型><类名>::<静态数据成员名>=<值>

(9)为了防止父类的影响,可以在子类定义一个与父类相同的静态变量,以屏蔽父类的影响。这里有一点需要注意:我们说静态成员为父类和子类共享,但我们有重复定义了静态成员,这会不会引起错误呢?不会,我们的编译器采用了一种绝妙的手法:name-mangling 用以生成唯一的标志

1、 静态数据成员

#include 
     
       
class Myclass { 
public: 
    Myclass(int a,int b,int c); 
    void GetSum(); 
private: 
    int a,b,c; 
    static int Sum;//声明静态数据成员 
}; 
int Myclass::Sum=0;//定义并初始化静态数据成员 

Myclass::Myclass(int a,int b,int c) 
{ 
    this->a=a; 
    this->b=b; 
    this->c=c; 
    Sum+=a+b+c; 
} 

void Myclass::GetSum() 
{ 
    cout < <"Sum=" < 
      
       
2、静态成员函数

#include 
        
          
class Myclass { 
    public: 
    Myclass(int a,int b,int c); 
    static void GetSum();/声明静态成员函数 
private: 
    int a,b,c; 
    static int Sum;//声明静态数据成员 
}; 
int Myclass::Sum=0;//定义并初始化静态数据成员 

Myclass::Myclass(int a,int b,int c) 
{ 
    this->a=a; 
    this->b=b; 
    this->c=c; 
    Sum+=a+b+c; //非静态成员函数可以访问静态数据成员 
} 

void Myclass::GetSum() //静态成员函数的实现 
{ 
    // cout < 
         
                首页 上一页   1 2 3  下一页 尾页 1/3/3