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();
您可以使用对象的现有实例(例如,为此目的定义的某个静态对象)或返回所需对象的函数的结果,而不是默认构造函数
但是,可以通过调用对象的析构函数删除对象,但保留其空间,也可以使用placementnew
在同一位置创建新对象:
*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.