C++ 类对象和 指针的区别

C++ 类对象和 指针的区别

转自:http://blog.csdn.net/ym19860303/article/details/8557746

指针的情况

class Test{
public:
int a;
Test(){
a = ;
}
}; int main()
{
Test* t1 = new Test();
t1->a = ; Test* t2 = new Test();
t2->a = ; 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 = ;
t2->a = ;
cout << "&t1:" << t1 << " a = " << t1->a << endl;
cout << "&t2:" << t2 << " a = " << t2->a <<endl; return ;
}

对象的情况:

class Test{
public:
int a;
Test(){
a = ;
}
};
int main()
{
Test t1;
t1.a = ; Test t2;
t2.a = ; 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 = ;
t2.a = ;
cout << "&t1:" << &t1 << " a = " << t1.a << endl;
cout << "&t2:" << &t2 << " a = " << t2.a <<endl; return ;
}

类的对象和类的指针的区别

转自: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; // 调用静态数据成员
}
};

类对象:Student s1      类指针:Student *s2

很关键的一点:定义对象实例时,分配了内存,指针变量则未分配类对象所需内存。

类的指针:他是一个内存地址值,他指向内存中存放的类对象(包括一些成员变量所赋的值).   
对象,他是利用类的构造函数在内存中分配一块内存(包括一些成员变量所赋的值).

指针变量是间接访问,但可实现多态(通过父类指针可调用子类对象),并且没有调用构造函数。 
直接声明可直接访问,但不能实现多态,声明即调用了构造函数(已分配了内存)。

类的对象:用的是内存栈,是个局部的临时变量.   
类的指针:用的是内存堆,是个永久变量,除非你释放它.

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 = ; // 静态数据成员初始化 int main(int argc, char** argv)
{
Student* s1;
s1 = new Student();
s1->set(""); Student s2;
s2.set(""); s1->print();
s2.print(); return ;
}

对于类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;

示例如下:

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

如何定义一个已声明的类:

Object::Object() {
m_num = ;
}
Object::~Object() { }
Object::Object(int num) {
m_num = num;
} int Object::getNumber() {
return m_num;
} void Object::setNumber(int num) {
m_num = num;
}

如何实例化和使用一个类:

int main () {
Object obj1;
Object obj2();
Object obj3 = Object();
Object *pObj4 = new Object();
Object *pObj5 = new Object();
Object objs[];
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 = ; i < ; i++) {
printf("objs[%d].getNumber() = %d\n",i, objs[i].getNumber());
}
delete pObj4;
delete pObj5;
return ;
}

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

对象与函数的关系(知道如何把对象指针和引用作为函数参数)

将对象指针作为函数的参数,传递给函数处理有两个好处

1、减少数据分配的时间和空间,提高了程序运行的效率;

2、在被调函数中,可以直接改变实参对象的值,实现函数之间的信息交换。

通过一个例子感受 对象指针作为函数的参数

#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(,);
}
int main()
{
CPoint p1(,),p2(,);
p1.copy(&p2); //把对象p2的地址赋值给对象指针
p1.disp();
func(&p2); //把对象p2的地址赋值给对象指针
p2.disp();
return ;
}

对象引用作为函数参数:比把对象指针作为函数参数更为普遍,因为使用对象引用作为函数参数不仅具有对象指针的优点,而且使用对象引用更为直观和简单。所以在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(,);
}
int main()
{
CPoint p1(,),p2(,);
p1.copy(p2); //把对象p2的地址赋值给对象引用
p1.disp();
func(p2); //把对象p2的地址赋值给对象引用
p2.disp();
return ;
}

对象数组(一串连续的对象)

举一个例子来感受对象数组的声明,初始化,和使用:

#include <iostream>
#include<string.h>
using namespace std;
class CStudent{
public:
CStudent(char *name,int age,int score);//构造函数
void disp();
private:
char m_name[]; //数据成员
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[]={CStudent("srf",,),CStudent("dp",,),
CStudent("aa",,),CStudent("bb",,)};
for(int i=;i<;i++)
{
csArray[i].disp(); //对象数组中的对象调用其成员函数
}
return ;
}

子对象和堆对象的声明和使用

一个类中的成员是另一个类的对象时,称这个对象是子对象。换句话说,子对象就是类的对象成员。例如下面的橘子类(COrange)和苹果类(CApple):

class COrange
{
public:
COrange();
private:
...
};
class CApple
{
public:
CApple();
private:
COrange orange; //橘子类的子对象
};

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(,,); //定义CApple类的对象apple
apple.disp();
return ;
}

堆对象:用类定义的对象有一种特殊的对象,可以在程序运行时,随时创建和删除,满足实时的程序要求,这种对象称为堆对象。

因为这种对象的内存空间是创建在堆内存中,所以可以像堆空间一样随时申请和释放,其操作符也是new和delete。

创建格式为:new 类名(参数名);

如:

CTest *p=NULL;   //定义一个对象指针
p=new CTest(); //创建一个堆对象,并赋值给对象指针p

也可以创建堆对象数组

CTest *pa=NULL;
pa = new CTest[];

删除时:

delete p;           //p是一个指向new创建的堆对象的对象指针
delete [] pa; //pa是一个指向new创建的堆对象数组的对象指针

通过一个例子来感受对对象的创建,删除和使用。

#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=;
m_b=;
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(,); //把对象指针指向新的堆对象,使用参数构造。
if(pheap)
{
pheap->disp();
delete pheap;
} return ;
}

堆对象如果创建失败,new返回是NULL值,即空指针,所以使用前必须进行判断,如果创建成功,则在最后不使用时,应当删除这个堆对象,并释放其占用的堆内存空间。

堆对象数组的创建,删除,和使用,只看主函数部分的修改:

int main()
{
CHeap *pheap;
pheap=new CHeap[]; //把对象指针指向堆对象数组的首元素
if(pheap) //判断是否创建成功
{
for(int i=;i<;i++)
{
(pheap+i)->disp(); //调用对象数组中对象元素的成员函数 使用对象指针加增量来访问对象数组中的每个对象元素
}
delete []pheap; //删除堆对象数组
} return ;
}

解析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;
};

现在我们需要在某个函数中要实现将一个A类型对象数据加入到一个CPtrArray对象中。此函数func1()如下:

void func1()
{
//首先定义一个A类型的对象
A a();
//使用pArray对象中的成员函数将此对象加入到容器中
pArray.Add(&a);
}

在另一个函数中我们使用pArray容器为我们保存的数据:

void func2()
{
//首先声明一个A类型的对象
A* a;
//使用pArray对象中的成员函数GetAt()将A类型的对象取出
for(int i; i < pArray.GetSize();i++)
{
a = (A*)pArray.GetAt(i);
//使用A中的数据进行相关的操作代码。***此时也可以使用delete释放指针指向的内存区块,防止内存泄露***当然是后面一种方法时才用到,暂时无视之。
...
} }

现在我们发现按照上面的过程,当我们在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();
//使用pArray对象中的成员函数将此对象加入到容器中
pArray.Add(a);
}

这样,我们就能够在func2函数中使用pArray对象中包含的数据了!那么为什么定义了一个指针类型的对象就能够完成了呢?还是一个局部对象呀,

前面说的func1函数执行完成后此对象还是要经历析构的啊!图解如下:

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

func1函数执行完成,a对象发生析构,pArray根据地址还能能够访问到之前的资源;

对,是要析构,但是,我们在pArray.Add(a);中加入的是a对象资源的地址,我们先看看A* a = new A(1);在堆中分配资源,我们知道,在堆中分配的资

源是在跟程序的生命周期是一致的。a对象虽然析构了(不存在了),因为a也是一个指针,a指针也就是保存这个资源的地址!我们在pArray中保存

的a的地址出的资源并没有析构!所以在func2函数中我们还能够使用此地址访问此地址对应的资源!

C++ 类对象和 指针的区别的更多相关文章

  1. <一>类,对象,this指针

    C++ 类:实体的抽象类型 实体(属性,行为) ->ADT(abstract data type) 类(属性->成员变量,行为->成员方法) OOP语言4大特征 抽象 封装/隐藏(通 ...

  2. class中new与未new的区别 类对象占用空间--转载

    转载自http://blog.sina.com.cn/shuiwuhendeboke    颗颗的博客 (1)作用域不同 不用new:作用域限制在定义类对象的方法中,当方法结束时,类对象也被系统释放了 ...

  3. C++用new和不用new创建类对象区别

    new创建类对象,使用完后需使用delete删除,跟申请内存类似.所以,new有时候又不太适合,比如在频繁调用场合,使用局部new类对象就不是个好选择,使用全局类对象或一个经过初始化的全局类指针似乎更 ...

  4. C++中怎么创建类对象

    在C++里,有两种方法创建对象:方法一:ClassName object(param);这样就声明了一个ClassName类型的object对象,C++会为它分配足够的存放对象所有成员的存储空间.注意 ...

  5. 不可或缺 Windows Native (18) - C++: this 指针, 对象数组, 对象和指针, const 对象, const 指针和指向 const 对象的指针, const 对象的引用

    [源码下载] 不可或缺 Windows Native (18) - C++: this 指针, 对象数组, 对象和指针, const 对象,  const 指针和指向 const 对象的指针, con ...

  6. C++:基类与派生类对象之间的赋值兼容关系

    4.5 基类与派生类对象之间的赋值兼容关系 在一定条件下,不同类型的数据之间可以进行类型转换,例如可以将整型数据赋给双精度型变量. 在赋值之前,先把整型数据转换为双精度型数据,然后再把它双精度型变量. ...

  7. C++@类对象和类指针的区别(转)

    原文地址不详 如下程序: #include <iostream> #include <string> using namespace std; class Student { ...

  8. C++类的对象和类的指针的区别

    #include <iostream> #include <string> using namespace std; class Student { public: stati ...

  9. 指向自身类型的成员指针的初始化,this不属于类对象的一部分

    有下面的一个简单的类: class CNullPointCall{public:    static void Test1();    void Test2();    void Test3(int  ...

随机推荐

  1. layui常用方法

    很好用的一个ui组件,弹出,分页等 http://layer.layui.com/ 1 带叉叉的弹窗 layer.open({ type: , title: false, //不显示标题 conten ...

  2. Docker - 入门

    术语 1. 镜像(image)与容器(container) 镜像是指文件系统快照或tar包. 容器是指镜像的运行态(时) 2.宿主机管理 设置/配置一台物理服务器或虚拟机,以便用于运行Docker容器 ...

  3. arm_GPIO_简单编程例题

    题目 分析下面的汇编led.s,查看S5PV210手册,说明程序的功能,和最终的运行结果,以及相关的硬件原理图,S5PV210手册可以在教学资源里的学习资料文件夹中下载. .equ   GPH3CON ...

  4. AnyImgUpload

    @{ ViewBag.Title = "ImgForAny"; Layout = null; } <h2>ImgForAny</h2> <script ...

  5. windows+ant+git+tomcat中ant直接获取git项目部署注意点

    最近项目搬迁到公司的"GitHub"上面原来的SVN的ant发布脚本要改下,于是百度ant获取git的方法太少了,windows平台上更是没有所以搞了两天,今天终于有点成果分享给大 ...

  6. 虚拟机安装windows服务出现无法打开内核设备“\\.Global\vmx86”

    解决方法: 在cmd下依次输入net start vmci,net start vmx86,net start VMnetuserif三个命令即可

  7. October 31st Week 45th Monday 2016

    While there is life there is hope. 一息若存,希望不灭. Go on living even if there is no hope. Knowing is not ...

  8. 【React】Stateless Function

    React创建组件的时候,有3种写法: // 1. 传统写法 const App = React.createClass({}); // 2. es6 的写法 class App extends Re ...

  9. Android中用TextView显示大量文字的方法

    最近学习Android中,试着实现一个简单的显示新闻Demo的时候,遇到了一个问题:一条新闻的内容文字很多,放在TextView上面超出屏幕了,怎么破? 查了一下资料,找到了两种方法实现: 1. 只用 ...

  10. ExtJS基础知识总结:常用控件使用方式(一)

    概述 最近一直在做相关ExtJs方面的项目,遇到了ExtJs使用方面的一系列问题,现在将使用技巧做个记录汇总,以便于下次能够快速使用.以下都是ExtJs控件的常用方法,做简单汇总,俗话说,好记星不如烂 ...