C++ C++;指针:更改内容而不更改地址?

C++ C++;指针:更改内容而不更改地址?,c++,pointers,C++,Pointers,假设我的许多类都使用了对象指针,但突然我想在不更改地址的情况下更改指针的内容 我认为object=newmycustomobject()将为对象提供一个新的指针地址,这是错误的吗?我希望在不更改指针地址的情况下创建新对象(是的,我将确保清除旧对象)。指针就是对象,因此如果执行new object()操作,您将创建一个新对象,但带有prevoius指针的函数将看不到它。如果要更改内容,可以这样做,因为知道指针的所有其他对象都将引用对象包含的值。这有点像一个全局变量。因此,您可以传递指针,所有函数在

假设我的许多类都使用了对象指针,但突然我想在不更改地址的情况下更改指针的内容


我认为
object=newmycustomobject()
将为对象提供一个新的指针地址,这是错误的吗?我希望在不更改指针地址的情况下创建新对象(是的,我将确保清除旧对象)。

指针就是对象,因此如果执行
new object()
操作,您将创建一个新对象,但带有prevoius指针的函数将看不到它。如果要更改内容,可以这样做,因为知道指针的所有其他对象都将引用对象包含的值。这有点像一个全局变量。因此,您可以传递指针,所有函数在访问对象时都会看到您所做的更改。

每次通过
new
操作符创建新对象时,系统都会在堆上为其寻找一个好的地址。你不能指示它给你一个特定的地址,即使你知道它是免费和可用的

您唯一能做的就是在某个地址更改对象的属性,比如存储在
int
变量中的数字


没错,运算符
new
返回一个新地址,或者说系统决定的地址。

实现分配器以返回相同的地址,并在new和delete运算符重载中使用它。

通常最好更改对象的属性(通过调用其方法)而不是删除它并创建一个新的。特别是,您可以通过指定完全替换对象,例如:

MyCustomObject * object=new MyCustomObject();
您可以使用对象的现有实例(例如,为此目的定义的某个静态对象)或返回所需对象的函数的结果,而不是默认构造函数

但是,可以通过调用对象的析构函数删除对象,但保留其空间,也可以使用placement
new
在同一位置创建新对象:

*object = MyCustomObject(); // Replace object with the result of default constructor.
#包括
类MyObject
{
公众:
MyObject(){std::cout内存中的对象
这是一个理解C中对象的内存如何工作的问题++

假设我们有以下对象:

#include <iostream>

class MyObject
{
public:
    MyObject()  { std::cout << "I was created at " << (void *) this << ".\n"; }
    ~MyObject() { std::cout << "Farewell from "    << (void *) this << ".\n"; }
};


int main(void)
{
    // Allocate space and create a new object.
    MyObject *p = new MyObject;

    // Destroy the object but leave the space allocated.
    p->~MyObject();

    // Create a new object in the same space.
    p = new (p) MyObject;

    // Delete the object and release the space.
    delete p;

    return 0;
}
它的大小将是20。(在大多数平台中)。因此在内存中它将如下所示:

class SimpleObject
{
public:
    char name[16];
    int age;
};
#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;
}
您可以手动更改内存,以便通过执行以下操作来创建对象:

Bytes
name             age
0000000000000000|0000|
//Manual assigment
staticMemory[0] = 'F';
staticMemory[1] = 'e';
staticMemory[2] = 'l';
staticMemory[3] = 0;

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

SimpleObject::SimpleObject(const char* name,int age)
{
    memcpy(this->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;    
#包括
#包括
#包括
#包括
类SimpleObject
{
公众:
字符名[16];
智力年龄;
SimpleObject(常量字符*名称,整数);
SimpleObject()
{
}
};
SimpleObject::SimpleObject(常量字符*名称,整数年龄)
{
memcpy(这个->名称,名称,16);
这个->年龄=年龄;
}
//静态内存中的对象
简单对象静态对象;
//静态内存中有20个字节
字符静态存储器[20];
int main()
{
//人工分配
静态内存[0]=“F”;
静态存储器[1]=“e”;
静态存储器[2]=“l”;
静态内存[3]=0;
int*age=reinterpret_cast(&staticMemory[16]);
*年龄=21岁;
printf(“在静态手动内存中,名称为%s%d年\n”,
重新解释\u cast(静态内存)->名称
,重新解释(静态记忆)->年龄;
//静态对象
新的(&staticObject)SimpleObject(“John”,23);
printf(“在静态对象中,名称为%s\n”,staticObject.name);
//静态存储器
SimpleObject*staticMemoryObject=重新解释强制转换(staticMemory);
新的(静态记忆对象)SimpleObject(“Jenny”,21岁);
printf(“在静态内存中,名称为%s\n”,staticMemoryObject->name);
//动态内存(堆)
void*dynamicMemoryObject=malloc(sizeof(SimpleObject));
新的(dynamicMemoryObject)SimpleObject(“Xavier”,22);
printf(“在动态内存中名称为%s\n”,重新解释\u cast(dynamicMemoryObject)->name);
free(dynamicMemoryObject);
//动态对象
SimpleObject*dynamicObject=新的SimpleObject(“Charles”,31);
printf(“在动态对象中,名称为%s\n”,dynamicObject->name);
printf(“动态对象的指针是%8X\n”,dynamicObject);
//用新放置替换动态对象
新的(动态对象)SimpleObject(“Charly”,31);
printf(“动态对象的新名称是%s\n”,dynamicObject->name);
printf(“动态对象的指针是%8X\n”,dynamicObject);
//用堆栈对象替换动态对象
SimpleObject stackObject(“Charl”,31);
memcpy(dynamicObject和stackObject,sizeof(SimpleObject));
printf(“动态对象的新名称是%s\n”,dynamicObject->name);
printf(“动态对象的指针是%8X\n”,dynamicObject);
//用新分配替换动态对象
dynamicObject=新的SimpleObject(“Sandy”,22);
printf(“动态对象的新名称是%s\n”,dynamicObject->name);
printf(“动态对象的指针是%8X\n”,dynamicObject);
返回0;
}
输出:

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

在静态对象中,名称为John

在静态存储器中,名字是珍妮

在动态内存中,名称是Xavier

在动态对象中,名称为Charles

动态对象的指针是4F8CF8

动态对象的新名称为Charly

动态对象的指针是4F8CF8

动态对象的新名称是Charl

动态对象的指针是4F8CF8

动态对象的新名称为Sandy

动态对象的指针为FD850


我认为你对指针和对象的概念有困难

对象是某种类型的实例。可以是int之类的基类型,也可以是s之类的用户定义类型
#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;
}
MyCustomObject* pObject1 = new MyCustomObject();

// ... do some stuff ...

pObject1->doStuff();
(*pObject1).doMoreStuff();

pObject1->value = 3;
(*pObject1).value = 4;

// ... do some stuff ...

// This copies the pointer, which points at original object instance
MyCustomObject* pObject2 = pObject1;

// Anything done to object pointed at by pObject2 will be seen via going
// through pointer pObject1.

pObject2->value = 2;
assert(pObject1->value == 2); // asserting that pObject1->value == pObject2->value
MyCustomObject object1;    // Note: no empty parenthesis ().
MyCustomObject object2(1); // Only use parenthesis if you actually are passing parameters.