C++ 類對象和 指針的區別 C++類和對象 解析C++普通局部變量與指針類型的對象變量的應用區別

C++ 類對象和 指針的區別html

C++ 類對象和 指針的區別ios

轉自:http://blog.csdn.net/ym19860303/article/details/8557746程序員

指針的狀況數組

class Test{
public:
    int a;
    Test(){
        a = 1;
    }
};

int main()
{
    Test* t1 = new Test();
    t1->a = 10;
    
    Test* t2 = new Test();
    t2->a = 5;
    
    cout << "&t1:" << t1 << " a = " << t1->a << endl;
    cout << "&t2:" << t2 <<  " a = " << t2->a <<endl;
    
    cout << "------------------------------" << endl;
    t2 = t1;
    cout << "&t1:" << t1 << " a = " << t1->a << endl;
    cout << "&t2:" << t2 <<  " a = " << t2->a <<endl;
    
    cout << "------------------------------" << endl;
    
    t1->a = 111;
    t2->a = 222;
    cout << "&t1:" << t1 << " a = " << t1->a << endl;
    cout << "&t2:" << t2 <<  " a = " << t2->a <<endl;
    
    return 0;
}
View Code

 

對象的狀況:app

class Test{
public:
    int a;
    Test(){
        a = 1;
    }
};
int main()
{
    Test t1;
    t1.a = 10;
    
    Test t2;
    t2.a = 5;
    
    cout << "&t1:" << &t1 << " a = " << t1.a << endl;
    cout << "&t2:" << &t2 <<  " a = " << t2.a <<endl;
    
    cout << "------------------------------" << endl;
    t2 = t1;
    cout << "&t1:" << &t1 << " a = " << t1.a << endl;
    cout << "&t2:" << &t2 <<  " a = " << t2.a <<endl;
    
    cout << "------------------------------" << endl;
    
    t1.a = 111;
    t2.a = 222;
    cout << "&t1:" << &t1 << " a = " << t1.a << endl;
    cout << "&t2:" << &t2 <<  " a = " << t2.a <<endl;
    
    return 0;
}
View Code

 

類的對象和類的指針的區別ide

轉自:http://blog.csdn.net/neuqbingoye/article/details/7184090函數

 class Student { 
     public: 
    static int number;  
    string name; 

     public: 
    Student() { } 

    void print()  // 態成員函數 print() 
    { 
        std::cout < < name < <" : The number of the students is " < < number < < " numbers." < < std::endl; // 調用靜態數據成員 
    } 
}; 
View Code

類對象:Student s1      類指針:Student *s2工具

很關鍵的一點:定義對象實例時,分配了內存,指針變量則未分配類對象所需內存。post

 

類的指針:他是一個內存地址值,他指向內存中存放的類對象(包括一些成員變量所賦的值).   
對象,他是利用類的構造函數在內存中分配一塊內存(包括一些成員變量所賦的值).   url

指針變量是間接訪問,但可實現多態(經過父類指針可調用子類對象),而且沒有調用構造函數。 
直接聲明可直接訪問,但不能實現多態,聲明即調用了構造函數(已分配了內存)。 

類的對象:用的是內存棧,是個局部的臨時變量.   
類的指針:用的是內存堆,是個永久變量,除非你釋放它.   

1.在類的聲明還沒有完成的狀況下,能夠聲明指向該類的指針,可是不可聲明該類的對象... 例如:含有純虛成員函數的抽象類。
2.父類的指針能夠指向子類的對象..

 

在應用時:   
        1.引用成員:   對象用"   .   "操做符;   指針用"   ->   "操做符.   
        2.生命期:     如果成員變量,則是類的析構函數來釋放空間;如果函數中的臨時變量,則做用域是該函數體內.而指針,則需利用delete   在相應的地方釋放分配的內存塊.   
        注意:用new   ,必定要delete..

 

C++的精髓之一就是多態性,只有指針或者引用能夠達到多態。對象不行
類指針的優勢: 
第一實現多態。 
第二,在函數調用,傳指針參數。無論你的對象或結構參數多麼龐大,你用指針,傳過去的就是4個字節。若是用對象,參數傳遞佔用的資源就太大了

 

類對象和類指針的區別

 轉自:http://blog.sina.com.cn/s/blog_73e0563201017c8u.html

此文章比較全面的總結了類對象和類指針使用的不一樣

#include <iostream> 
#include <string> 
using namespace std; 

class Student 
{ 
    public: 
    static int number; 
    string name; 

public: 
    Student() { } 

    void set(string str) 
    { 
       name = str; 
        number++; // 調用靜態數據成員 
    } 

    void print() // 態成員函數 print() 
    { 
        std::cout < < name < <" : The number of the students is " < < number < < " numbers." < < std::endl; // 調用靜態數據成員 
    } 
}; 

int Student::number = 0; // 靜態數據成員初始化 

int main(int argc, char** argv) 
{ 
    Student* s1; 
    s1 = new Student(); 
    s1->set("111"); 

    Student s2; 
    s2.set("222"); 

    s1->print(); 
    s2.print(); 

    return 0; 
} 
View Code

對於類student ,定義了一個對象 和一個指針。

 

類的指針:他是一個內存地址值,他指向內存中存放的類對象(包括一些成員變量所賦的值).   
對象,他是利用類的構造函數在內存中分配一塊內存(包括一些成員變量所賦的值).   
          在應用時:   
        1.引用成員:   對象用"   .   "操做符;   指針用"   ->   "操做符.   
        2.生命期:     如果成員變量,則是類的析構函數來釋放空間;如果函數中的臨時變量,則做用域是該函數體內.而指針,則需利用delete   在相應的地方釋放分配的內存塊.   
注意:用new   ,必定要delete..

類的對象:用的是內存棧,是個局部的臨時變量.   
類的指針:用的是內存堆,是個永久變量,除非你釋放它.   
    
當類是有虛函數的基類,Func是它的一個虛函數,則調用Func時:   
類的對象:調用的是它本身的Func;   
類的指針:調用的是分配給它空間時那種類的Func;  

對於一個類的對象和這個類的指針(用new運算符分配內存)在應用時有何區別   
1.類和對象是兩回事,對象是類的實例;   
2.對象是在棧中分配的,使用new生成的對象是在堆中分配的;   
3.要發揮虛函數的強大做用,必須使用指針來訪問對象.  

指針能夠實現多態,直接用對象不行 
執行定義對象,在棧空間 
new的在堆

 

類型決定了你能作什麼.

其實做用基本同樣 都是爲了調用類的成員變量 和成員函數用的 
當你但願明確使用這個類的時候,最好使用對象,若是你但願使用C++中的動態綁定,則最好使用指針或者引用 
指針和引用用起來更靈活,容易實現多態等

 

1.在類的聲明還沒有完成的狀況下,能夠聲明指向該類的指針,可是不可聲明該類的對象... 
2.父類的指針能夠指向子類的對象..

定義對象實例時,分配了內存。指針變量則未分配類對象所需內存,除非new了

指針變量是間接訪問,但可實現多態(經過父類指針可調用子類對象),而且沒有調用構造函數。 
直接聲明可直接訪問,但不能實現多態,聲明即調用了構造函數(已分配了內存)。 
至於那個效率高要看程序調用過程而定。

C++的精髓之一就是多態性,只有指針或者引用能夠達到多態。對象不行

用指針: 
第一實現多態。 
第二,在函數調用,傳指針參數。無論你的對象或結構參數多麼龐大,你用指針,傳過去的就是4個字節。若是用對象,參數傳遞佔用的資源就太大了

 

C++類和對象

轉自:http://www.cnblogs.com/ggjucheng/archive/2011/12/14/2287381.html

C++類就是爲程序員提供一種創建一個新類型的工具,使這些新類型的使用可以像內部類型同樣方便。

一個類就是一個用戶定義的類型,如何聲明一個類,形式以下:

class class_name {
  access_specifier_1:
    member1;
  access_specifier_2:
    member2;
  ...
  } object_names;
View Code

示例以下:

class Object {
public:
    Object();
    ~Object(); //must be public
    Object(int num);
    int getNumber();
    void setNumber(int num);
                    
private:
    int m_num;           
};
View Code

如何定義一個已聲明的類:

Object::Object() {
    m_num = 0;
}
Object::~Object() {

}
Object::Object(int num) {
    m_num = num;
}

int Object::getNumber() {
    return m_num;
}

void Object::setNumber(int num) {
     m_num = num;
}
View Code

如何實例化和使用一個類:

int main () {
    Object obj1;
    Object obj2(110);
    Object obj3 = Object(119);
    Object *pObj4 = new Object();
    Object *pObj5 = new Object(119);
    Object objs[10];
    printf("obj1.getNumber() = %d\n", obj1.getNumber());
    printf("obj2.getNumber() = %d\n", obj2.getNumber());
    printf("obj3.getNumber() = %d\n", obj3.getNumber());
    printf("pObj4->getNumber() = %d\n", pObj4->getNumber());
    printf("pObj5->getNumber() = %d\n", pObj5->getNumber());
    for (int i = 0; i < 10; i++) {
        printf("objs[%d].getNumber() = %d\n",i, objs[i].getNumber());
    }
    delete pObj4;
    delete pObj5;
    return 0;
}
View Code

struct 和union的類聲明

類能夠定義不只能夠用關鍵字class,也能夠用關鍵字struct和union。

class和struct的概念是類似的,可用struct和class聲明C++的類(即struct能夠有數據成員和函數成員)。二者之間惟一的區別是使用關鍵字struct聲明的類成員默認狀況下,是public訪問權限,而使用關鍵字class聲明的類成員默認是private訪問權限。對於全部其餘的目的,這兩個關鍵字是等價的。

union的概念是與struct和class聲明類不一樣的,由於union一次只能存儲一個數據成員,但union也可能擁有函數成員,union類的默認訪問權限是public。

 

C++新特性(類與對象的各類指針和引用)

轉自:http://blog.csdn.net/pearl333/article/details/8027358

 

對象與函數的關係(知道如何把對象指針和引用做爲函數參數) 

將對象指針做爲函數的參數,傳遞給函數處理有兩個好處

一、減小數據分配的時間和空間,提升了程序運行的效率;

二、在被調函數中,能夠直接改變實參對象的值,實現函數之間的信息交換。

經過一個例子感覺 對象指針做爲函數的參數

#include <iostream>
using namespace std;
class CPoint{
    public :
        CPoint(int x,int y);
        void copy(CPoint *point); //在成員函數中,參數是對象指針
        void setXY(int x,int y);
        void disp();
    private:
        int m_x;            //數據成員
        int m_y;
};
CPoint::CPoint(int x,int y)     //帶參數的構造函數
{
    m_x=x;
    m_y=y;
}
void CPoint::copy(CPoint *point)
{
    m_x=point->m_x;          //經過對象指針訪問該對象的數據成員,賦值
    m_y=point->m_y;                   //給調用成員函數的對象的數據成員
}
void CPoint::disp(){
    cout<<"x="<<m_x<<";y="<<m_y<<endl;
    }
void CPoint::setXY(int x,int y){
    m_x=x;
    m_y=y;
}
void func(CPoint *p){           //函數的參數是對象指針,經過指針調用對象的成員函數
    p->setXY(55,33);
}
int main()
{
    CPoint p1(5,5),p2(25,25);
    p1.copy(&p2);              //把對象p2的地址賦值給對象指針
    p1.disp();
    func(&p2);              //把對象p2的地址賦值給對象指針
    p2.disp();
    return 0;
}
View Code

對象引用做爲函數參數:比把對象指針做爲函數參數更爲廣泛,由於使用對象引用做爲函數參數不只具備對象指針的優勢,並且使用對象引用更爲直觀和簡單。因此在C++中廣泛採用對象引用做爲函數參數,看例子,注意對比上面的程序:

#include <iostream>
using namespace std;
class CPoint{
    public :
        CPoint(int x,int y);
        void copy(CPoint &point); //在成員函數中,參數是對象指針
        void setXY(int x,int y);
        void disp();
    private:
        int m_x;            //數據成員
        int m_y;
};
CPoint::CPoint(int x,int y)     //帶參數的構造函數
{
    m_x=x;
    m_y=y;
}
void CPoint::copy(CPoint &point)  //函數的參數是對象引用
{
    m_x=point.m_x;          //經過對象引用訪問該對象數據成員,賦值給調用成員函數的對象的數據成員
    m_y=point.m_y;
}
void CPoint::disp(){
    cout<<"x="<<m_x<<";y="<<m_y<<endl;
    }
void CPoint::setXY(int x,int y){
    m_x=x;
    m_y=y;
}
void func(CPoint &p){           //在通常函數中,參數是對象引用,經過對象引用調用成員函數
    p.setXY(55,33);
}
int main()
{
    CPoint p1(5,5),p2(25,25);
    p1.copy(p2);              //把對象p2的地址賦值給對象引用
    p1.disp();
    func(p2);              //把對象p2的地址賦值給對象引用
    p2.disp();
    return 0;
}
View Code

對象數組(一串連續的對象)

舉一個例子來感覺對象數組的聲明,初始化,和使用:

#include <iostream>
#include<string.h>
using namespace std;
class CStudent{
    public:
        CStudent(char *name,int age,int score);//構造函數
        void disp();
    private:
        char m_name[16];                //數據成員
        int m_age;
        int m_score;
};
CStudent::CStudent(char *name,int age,int score){         //構造函數的實現
    strcpy(m_name,name);
    m_age=age;
    m_score=score;
}
void CStudent::disp()                             //顯示構造函數
{
    cout<<"name:"<<m_name<<";age:"<<m_age<<";score:"<<m_score<<endl;
}
int main()
{
   CStudent csArray[4]={CStudent("srf",24,96),CStudent("dp",23,95),
        CStudent("aa",24,98),CStudent("bb",24,99)};
    for(int i=0;i<4;i++)
    {
        csArray[i].disp();                           //對象數組中的對象調用其成員函數
    }
    return 0;
}
View Code

子對象和堆對象的聲明和使用

一個類中的成員是另外一個類的對象時,稱這個對象是子對象。換句話說,子對象就是類的對象成員。例以下面的橘子類(COrange)和蘋果類(CApple):

class COrange
{
    public:
        COrange();
    private:
        ...
};
class CApple
{
    public:
        CApple();
    private:
        COrange orange;              //橘子類的子對象
};
View Code

CApple的成員orange是類COrange的對象,因此orange爲子對象。當一個類中包含子對象時,這個類的構造函數中應該包含對該子對象的初始化後。而且只能採用成員初始化表的方法來初始化該子對象。經過例子感覺:

包含對象成員的類應用。

#include <iostream>
#include<string.h>
using namespace std;
class COrange
{
    public:
        COrange(int heft,int sweet);
        void disp();
    private:
        int m_heft;
        int m_sweet;
};
COrange::COrange(int heft,int sweet)
{
    m_heft=heft;
    m_sweet=sweet;
}
void COrange::disp()
{
    cout<<m_heft<<";"<<m_sweet<<endl;
}
class CApple
{
    public:
        CApple(int heft,int sweet,int fragrant);
        void disp();
    private:
        COrange orange;         //聲明COrange類的子對象orange
        int m_fragrant;                 //數據成員--香味
};
CApple::CApple(int heft,int sweet,int fragrant):orange(heft,sweet)
{                              //用成員初始化列表的方式初始化子對象,格式爲:子對象名(參數表)
    m_fragrant=fragrant;
}
void CApple::disp(){
    orange.disp();
    cout<<m_fragrant<<endl;
}
int main()
{
    CApple apple(8,18,28);          //定義CApple類的對象apple
    apple.disp();
    return 0;
}
View Code

堆對象:用類定義的對象有一種特殊的對象,能夠在程序運行時,隨時建立和刪除,知足實時的程序要求,這種對象稱爲堆對象。

由於這種對象的內存空間是建立在堆內存中,因此能夠像堆空間同樣隨時申請和釋放,其操做符也是new和delete。

建立格式爲:new 類名(參數名);

如:

CTest *p=NULL;   //定義一個對象指針
p=new CTest();    //建立一個堆對象,並賦值給對象指針p
View Code

也能夠建立堆對象數組

CTest *pa=NULL;
pa = new CTest[5];
View Code

刪除時:

delete p;           //p是一個指向new建立的堆對象的對象指針
delete [] pa;          //pa是一個指向new建立的堆對象數組的對象指針
View Code

經過一個例子來感覺對對象的建立,刪除和使用。

#include <iostream>
#include<string.h>
using namespace std;
class CHeap
{
    public:
        CHeap();
        CHeap(int a,int b);
        ~CHeap();
        void disp();
    private:
        int m_a,m_b;
};
CHeap::CHeap()
{
    m_a=0;
    m_b=0;
    cout<<"調用默認的構造函數"<<endl;
}
CHeap::CHeap(int a,int b)
{
    m_a=a;
    m_b=b;
    cout<<"調用帶參數的構造函數"<<endl;
}
CHeap::~CHeap()
{
    cout<<"調用析構函數"<<endl;
}
void CHeap::disp()
{
    cout<<"m_a="<<m_a<<";m_b="<<m_b<<endl;
}
int main()
{
    CHeap *pheap;
    pheap=new CHeap(); //建立堆對象,並把地址賦值給pheap
    if(pheap)                //判斷是否建立成功
    {
        pheap->disp();  //經過對象指針,調用堆對象的成員函數
        delete pheap;      //刪除堆對象
    }
    pheap = new CHeap(10,30); //把對象指針指向新的堆對象,使用參數構造。
       if(pheap)
    {
        pheap->disp();
        delete pheap;
    }

    return 0;
}
View Code

堆對象若是建立失敗,new返回是NULL值,即空指針,因此使用前必須進行判斷,若是建立成功,則在最後不使用時,應當刪除這個堆對象,並釋放其佔用的堆內存空間。

堆對象數組的建立,刪除,和使用,只看主函數部分的修改:

int main()
{
    CHeap *pheap;
    pheap=new CHeap[3]; //把對象指針指向堆對象數組的首元素
    if(pheap)                //判斷是否建立成功
    {
      for(int i=0;i<3;i++)
      {
          (pheap+i)->disp(); //調用對象數組中對象元素的成員函數   使用對象指針加增量來訪問對象數組中的每一個對象元素
      }
        delete []pheap;      //刪除堆對象數組
    }
   

    return 0;
}
View Code

 

解析C++普通局部變量與指針類型的對象變量的應用區別

轉自:http://www.cnblogs.com/hellope/archive/2011/08/03/2126371.html

首先咱們先來了解一下MFC中的CPtrArray類,他能夠說是CObject類型指針對象的集合。經過int Add(CObject* newElement );注意參數是一個指針類型)能夠向集合中添加元素。首先咱們定義一個CPtrArray類型的對象。

CPtrArray pArray;//他是一個全局對象

先設定一個舉例的類類型。如:

class A
{
public:
    A(int i)
    {
        a = i;
    }
    ~A(){}
public:
    int a;
};
View Code

如今咱們須要在某個函數中要實現將一個A類型對象數據加入到一個CPtrArray對象中。此函數func1()以下:

void func1()
{
    //首先定義一個A類型的對象
    A a(1);
    //使用pArray對象中的成員函數將此對象加入到容器中
    pArray.Add(&a);
}
View Code

在另外一個函數中咱們使用pArray容器爲咱們保存的數據:

void func2()
{
    //首先聲明一個A類型的對象
    A* a;
    //使用pArray對象中的成員函數GetAt()將A類型的對象取出
    for(int i; i < pArray.GetSize();i++)
    {
        a = (A*)pArray.GetAt(i);
        //使用A中的數據進行相關的操做代碼。***此時也可使用delete釋放指針指向的內存區塊,防止內存泄露***固然是後面一種方法時纔用到,暫時無視之。
        ...
    }
     
}
View Code

如今咱們發現按照上面的過程,當咱們在func2()函數中將要使用pArray容器對象爲咱們保存的數據時,咱們並不能獲得想要的數據!!!爲何發生以上狀況?圖解以下

 

pArray保存a保存資源的地址;

func1函數執行完成,a發生析構,資源不可用;

原來在func1()函數中,a對象是一個局部對象,當咱們使用pArray.Add(&a);咱們將a對象的地址保存到pArray對象中。可是做爲局部對象,當func1

執行完成後,資源須要回收,此時咱們定義的a對象也在A類中的析構函數中被析構釋放資源!而當咱們在fun2()函數中執行取出保存的對象時,

實際是根據保存的地址去內存中找到數據,雖然此時咱們能可以找到此地址,可是這個地址上面的數據並非咱們須要的了!!!因此才發生面的狀況!

那麼怎麼才能解決呢?

看下面,咱們只需更改func1函數中的代碼:

void func1()
{
    //首先定義一個A類型的對象
    //A a(1);//爲對比,只是註釋原來那句
    A* a = new A(1);
    //使用pArray對象中的成員函數將此對象加入到容器中
    pArray.Add(a);
}
View Code

這樣,咱們就可以在func2函數中使用pArray對象中包含的數據了!那麼爲何定義了一個指針類型的對象就可以完成了呢?仍是一個局部對象呀,

前面說的func1函數執行完成後此對象仍是要經歷析構的啊!圖解以下:

pArray中保存a指向資源的地址;

func1函數執行完成,a對象發生析構,pArray根據地址還能可以訪問到以前的資源;

對,是要析構,可是,咱們在pArray.Add(a);中加入的是a對象資源的地址,咱們先看看A* a = new A(1);在堆中分配資源,咱們知道,在堆中分配的資

源是在跟程序的生命週期是一致的。a對象雖然析構了(不存在了),由於a也是一個指針,a指針也就是保存這個資源的地址!咱們在pArray中保存

的a的地址出的資源並無析構!因此在func2函數中咱們還可以使用此地址訪問此地址對應的資源!

相關文章
相關標籤/搜索