从类级别放置内访问成员 新的重载
Accessing member from within class-level placement new overload
从类中定义的放置新重载中访问类的数据成员是否合法?
#include <iostream>
#include <cstdlib>
using namespace std;
class MyClass
{
public:
MyClass ()
{
// Non-default constructor to make sure m_BaseAddress doesn't get
// overwritten.
}
// T is some class that directly or indirectly inherits from MyClass.
template<typename T>
static void* operator new (size_t /* numBytes */, T* memory)
{
auto object = static_cast<MyClass*>(memory);
object->m_BaseAddress = memory;
return static_cast<void*>(memory);
}
template<typename T>
static void operator delete (void* /* memory */, T* /* memory */)
{
}
void* GetBaseAddress ()
{
return m_BaseAddress;
}
private:
void* m_BaseAddress;
};
int wmain ()
{
auto memory = reinterpret_cast<MyClass*>(malloc(sizeof(MyClass)));
auto object = new (memory) MyClass();
wcout << L"Expected: " << memory << endl;
wcout << L"Actual: " << object->GetBaseAddress() << endl;
return 0;
}
我正在使用模板化放置-new,试图使其工作,即使"newed"是从MyClass
继承的类的实例。
用例:我使用一个特殊的分配器为对象分配内存。有一些与分配的内存关联的辅助属性,如果我为它提供分配内存的基址,我可以从此分配器查询这些属性。为了处理此基址的放置-new和存储,我使用了一个类(在上面的示例中MyClass
(,我将其用作需要在此特殊堆上分配的所有类的基类。由于 placement-new 已经将基址作为参数获取,我想知道我是否可以直接设置成员,而不是要求它在构造函数中作为参数传递。
您发布的代码具有未定义的行为,在运行构造函数之前使用放置new
。这意味着你在MyClass
的构造函数运行之前引用MyClass::m_BaseAddress
,所以static_cast
是谎言,程序是无效的。
该标准明确指出这是第 3.8.5 节对象生存期中未定义的行为(强调我的(。
在对象的生存期开始之前,但在分配了对象将占用的存储之后,或者在对象的生存期结束之后,在重新使用或释放对象占用的存储之前,可以使用任何指向对象将要或曾经所在的存储位置的指针,但只能以有限的方式使用。对于正在建造或销毁的物体,请参见 12.7。否则,此类指针引用分配的存储 (3.7.4.2(,并且像指针的类型为
void*
一样使用该指针是明确定义的。可以取消引用此类指针,但生成的左值只能以有限的方式使用,如下所述。在以下情况下,程序具有未定义的行为:
• 对象将是或曾经是具有非平凡析构函数的类类型,并且指针用作删除表达式的操作数,
• 指针用于访问对象的非静态数据成员或调用对象的非静态成员函数
您可以通过向代码添加一些打印件来看到这种情况。
该程序可能会在这种未定义的行为下正常工作,但它仍然是一个无效的C++程序,应该避免。
请忽略以前对此答案的编辑:(
- 这是关于成员访问规则的正确摘要吗
- 为什么我在空指针错误(链表)中获取成员访问权限
- 成员访问是否在空指针上定义C++?
- C++ IDE 不会推断/自动完成对模板类中的 std::array 下标表达式的成员访问
- 为什么类成员数据必须是静态的才能被模板化类的模板化结构成员访问
- 为什么c++允许成员函数定义中实例的私有成员访问
- C/C++ 包含点的宏参数(成员访问运算符)
- 访问说明符(私有/公共/受保护)如何在内部工作(限制成员访问)?
- 如何将超类的受保护成员访问到其派生类. 如果已在派生类中声明了具有相同名称的函数?
- 内部类私有成员访问和封闭的友好性
- 通过 C++ 中的另一个结构成员访问结构
- 具体化 PRVALUES 成员访问的 decltype 行为不正确
- 常量表达式中的静态成员访问
- XVALUE来自类成员访问表达式
- 未经授权的私有类成员访问会产生编译时错误而不是运行时错误?
- 在 c++ 中,为什么 -> 被称为二进制中缀指针成员访问运算符?
- 如何访问模板参数的成员?“成员访问不完整的类型”
- 不明确的可变参数类成员访问
- C 受保护的成员访问
- 将typeID转换为静态成员访问(C )的命名空间