C ++指针:改变内容而不改变地址? [英] C++ Pointer: changing the contents without changing the address?

查看:156
本文介绍了C ++指针:改变内容而不改变地址?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  MyCustomObject * object = new MyCustomObject() 

假设对象指针被我的许多类使用,但突然我想改变指针的内容不改变地址。



我认为 object = new MyCustomObject()会给对象一个新的指针地址吗?我想要新的对象而不改变指针地址(是的,我将确保清除旧的对象)。

解决方案

in memory



这是理解C ++中对象的内存如何工作的原因



让我们想象一下,以下对象:

  class SimpleObject 
{
public:
char name [16]
int age;
};

它的大小将为20.(在大多数平台上)。所以在内存中它将看起来像这样:

 字节
名称age
0000000000000000 |

您可以手动更改内存,以便通过执行以下操作来创建对象:

  //手动分配
staticMemory [0] ='F';
staticMemory [1] ='e';
staticMemory [2] ='l';
staticMemory [3] = 0;

int * age = reinterpret_cast< int *>(& staticMemory [16]);
* age = 21;

您可以通过执行以下操作成功创建对象:

  printf(在静态手动存储器中,名称为%s%d years old \\\

reinterpret_cast< SimpleObject *>(staticMemory) > name
,reinterpret_cast< SimpleObject *>(staticMemory) - > age);

哪些输出:


在静态手动记忆中,名字为Fel 21岁


由于显而易见的实际原因,但它有助于了解对象是如何存储的。



新操作符



新操作符基本上如下所示:


  1. 在堆内存中以字节为单位分配对象大小

  2. 调用对象构造函数来填充内存

根据具体实现,它更复杂,但想法是一样的。



  SimpleObject :: SimpleObject(const char * name,int age)
{
memcpy - > name,name,16);
this-> age = age;
}

此代码:

  SimpleObject * dynamicObject = new SimpleObject(Charles,31); 

将几乎等同于:

  SimpleObject * dynamicMemoryObject =(SimpleObject *)malloc(sizeof(SimpleObject)); 
memcpy(dynamicMemoryObject-> name,Charles,16);
dynamicMemoryObject-> age = 31;

因为我说的有点复杂,但是想法是一样的。 p>

替换内存中的对象



现在可以理解,有很多方法可以替换同一内存中的对象空间,最常见的方式是放置新。以下是许多示例:

  #include< cstdlib> 
#include< cstdio>
#include< cstring>
#include< new>

class SimpleObject
{
public:
char name [16];
int age;

SimpleObject(const char * name,int age);
SimpleObject()
{
}
};


SimpleObject :: SimpleObject(const char * name,int age)
{
memcpy(this-> name,name,16);
this-> age = age;
}

//静态内存中的对象
SimpleObject staticObject;

//静态内存中的20个字节
char staticMemory [20];

int main()
{
//手动分配
staticMemory [0] ='F';
staticMemory [1] ='e';
staticMemory [2] ='l';
staticMemory [3] = 0;

int * age = reinterpret_cast< int *>(& staticMemory [16]);
* age = 21;
printf(在静态手动内存中,名称为%s%d岁old \\\

reinterpret_cast< SimpleObject *>(staticMemory) - > name
,reinterpret_cast& *>(staticMemory) - > age);

//静态对象
new(& staticObject)SimpleObject(John,23);
printf(在静态对象名称为%s\\\
,staticObject.name);

//静态内存
SimpleObject * staticMemoryObject = reinterpret_cast< SimpleObject *>(staticMemory);
new(staticMemoryObject)SimpleObject(Jenny,21);
printf(在静态存储器中名称为%s\\\
,staticMemoryObject-> name);

//动态内存(堆)
void * dynamicMemoryObject = malloc(sizeof(SimpleObject));
new(dynamicMemoryObject)SimpleObject(Xavier,22);
printf(在动态存储器中名字是%s \\\
,reinterpret_cast< SimpleObject *>(dynamicMemoryObject) - > name);
free(dynamicMemoryObject);

//动态对象
SimpleObject * dynamicObject = new SimpleObject(Charles,31);
printf(在动态对象中名称为%s\\\
,dynamicObject-> name);
printf(dynamic object is Pointer of%8X \\\
,dynamicObject);

//用放置替换动态对象new
new(dynamicObject)SimpleObject(Charly,31);
printf(动态对象的新名称是%s\\\
,dynamicObject-> name);
printf(dynamic object is Pointer of%8X \\\
,dynamicObject);

//用堆栈对象替换动态对象
SimpleObject stackObject(Charl,31);
memcpy(dynamicObject& stackObject,sizeof(SimpleObject));
printf(动态对象的新名称是%s\\\
,dynamicObject-> name);
printf(dynamic object is Pointer of%8X \\\
,dynamicObject);

//用新的分配替换动态对象
dynamicObject = new SimpleObject(Sandy,22);
printf(动态对象的新名称是%s\\\
,dynamicObject-> name);
printf(dynamic object is Pointer of%8X \\\
,dynamicObject);

return 0;
}

输出:



< blockquote>

在静态手动内存中,名称为Fel 21岁



在静态对象中,名称为John



在静态记忆中,名称为Jenny



在动态记忆中,名称为Xavier



在动态对象中名为Charles



动态对象的指针为4F8CF8



动态对象的新名称是Charly



动态对象的指针是4F8CF8



动态对象的新名称是Charl



动态对象的指针是4F8CF8



动态对象的新名称是Sandy



动态对象的指针是FD850



MyCustomObject * object=new MyCustomObject();

Assume the object pointer is used by many of my classes, but all of a sudden I want to change the contents of the pointer without changing the address.

Am I wrong in thinking that object = new MyCustomObject() will give a new pointer address to the object? I want the new object without changing the pointer address (Yes, I will make sure to clean the old object).

解决方案

Objects in Memory

This is a matter of understand how memory works for objects in C++

Lets imagine we have the following object:

class SimpleObject
{
public:
    char name[16];
    int age;
};

It's size will be 20. (In most platforms). So in memory it will look like this:

Bytes
name             age
0000000000000000|0000|

You can change memory manually so you could create the object by doing something like:

//Manual assigment
staticMemory[0] = 'F';
staticMemory[1] = 'e';
staticMemory[2] = 'l';
staticMemory[3] = 0;

int* age = reinterpret_cast<int*>(&staticMemory[16]);
*age = 21;

You can prove object is successfully created by doing something like:

printf("In static manual memory the name is %s %d years old\n",
     reinterpret_cast<SimpleObject*>(staticMemory)->name
     ,reinterpret_cast<SimpleObject*>(staticMemory)->age);

Which outputs:

In static manual memory the name is Fel 21 years old

By obvious practical reasons this is not used in real life, but it helps understand how objects are storage.

New operator

New operator basically works as this:

  1. Allocate the size of the object in bytes in the heap memory
  2. Call the object constructor to fill the memory

It's more complicated depending on the implementation, but the idea is the same.

So if the constructor is:

SimpleObject::SimpleObject(const char* name,int age)
{
    memcpy(this->name,name,16);
    this->age = age;
}

This code:

SimpleObject* dynamicObject = new SimpleObject("Charles",31);

Will be almost equivalent to:

SimpleObject* dynamicMemoryObject = (SimpleObject*)malloc( sizeof(SimpleObject) );
memcpy(dynamicMemoryObject->name,"Charles",16);
dynamicMemoryObject->age = 31;    

As I said is a little bit more complicated than that, but the idea is the same.

Replacing an object in memory

Now that this is understood there are many ways to replace an object in the same memory space, the most common way is placement new. Many examples below:

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <new>

class SimpleObject
{
public:
    char name[16];
    int age;

    SimpleObject(const char* name,int age);
    SimpleObject()
    {
    }
};


SimpleObject::SimpleObject(const char* name,int age)
{
    memcpy(this->name,name,16);
    this->age = age;
}

//Object in static memory
SimpleObject staticObject;

//20 bytes in static memory
char staticMemory[20];

int main()
{
    //Manual assigment
    staticMemory[0] = 'F';
    staticMemory[1] = 'e';
    staticMemory[2] = 'l';
    staticMemory[3] = 0;

    int* age = reinterpret_cast<int*>(&staticMemory[16]);
    *age = 21;
    printf("In static manual memory the name is %s %d years old\n",
        reinterpret_cast<SimpleObject*>(staticMemory)->name
        ,reinterpret_cast<SimpleObject*>(staticMemory)->age);

    //Static object
    new (&staticObject) SimpleObject("John",23);
    printf("In static object the name is %s\n",staticObject.name);

    //Static memory
    SimpleObject* staticMemoryObject = reinterpret_cast<SimpleObject*>(staticMemory);
    new (staticMemoryObject) SimpleObject("Jenny",21);
    printf("In static memory the name is %s\n",staticMemoryObject->name);

    //Dynamic memory (heap)
    void* dynamicMemoryObject = malloc( sizeof(SimpleObject) );
    new (dynamicMemoryObject) SimpleObject("Xavier",22);
    printf("In dynamic memory the name is %s\n",reinterpret_cast<SimpleObject*>(dynamicMemoryObject)->name);
    free(dynamicMemoryObject);

    //Dynamic object
    SimpleObject* dynamicObject = new SimpleObject("Charles",31);
    printf("In a dynamic object the name is %s\n",dynamicObject->name);
    printf("Pointer of dynamic object is %8X\n",dynamicObject);

    //Replacing a dynamic object with placement new
    new (dynamicObject) SimpleObject("Charly",31);
    printf("New name of dynamic object is %s\n",dynamicObject->name);
    printf("Pointer of dynamic object is %8X\n",dynamicObject);

    //Replacing a dynamic object with stack object
    SimpleObject stackObject("Charl",31);
    memcpy(dynamicObject,&stackObject,sizeof(SimpleObject));
    printf("New name of dynamic object is %s\n",dynamicObject->name);
    printf("Pointer of dynamic object is %8X\n",dynamicObject);

    //Replacing a dynamic object with a new allocation
    dynamicObject = new SimpleObject("Sandy",22);
    printf("New name of dynamic object is %s\n",dynamicObject->name);
    printf("Pointer of dynamic object is %8X\n",dynamicObject);

    return 0;
}

With output:

In static manual memory the name is Fel 21 years old

In static object the name is John

In static memory the name is Jenny

In dynamic memory the name is Xavier

In a dynamic object the name is Charles

Pointer of dynamic object is 4F8CF8

New name of dynamic object is Charly

Pointer of dynamic object is 4F8CF8

New name of dynamic object is Charl

Pointer of dynamic object is 4F8CF8

New name of dynamic object is Sandy

Pointer of dynamic object is FD850

这篇关于C ++指针:改变内容而不改变地址?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆