C++ 我可以显式调用类的构造函数和析构函数吗?
不知何故,我需要在预先分配的内存中使用class对象。但是,g++不喜欢下面的代码。它在说C++ 我可以显式调用类的构造函数和析构函数吗?,c++,constructor,g++,destructor,C++,Constructor,G++,Destructor,不知何故,我需要在预先分配的内存中使用class对象。但是,g++不喜欢下面的代码。它在说 第26行中“CTest::CTest”的使用无效 如何更改此项以使其正常工作 #include <stdio.h> #include <stdlib.h> #include <string> class CTest { public: CTest(const char* str) { printf("co
第26行中“CTest::CTest”的使用无效
如何更改此项以使其正常工作
#include <stdio.h>
#include <stdlib.h>
#include <string>
class CTest
{
public:
CTest(const char* str)
{
printf("constructor\n");
m_str = str;
}
virtual ~CTest()
{
printf("destructor\n");
}
void output()
{
printf("output:%s\n", m_str.c_str());
}
protected:
std::string m_str;
};
struct TTT
{
char test_ptr[sizeof(CTest)];
};
int main(int argc, char* argv[])
{
struct TTT* ttt = (struct TTT*)malloc(sizeof(struct TTT));
CTest* test = (CTest*)(ttt->test_ptr);
test->CTest("123456");
test->output();
test->~CTest();
return 0;
}
#包括
#包括
#包括
类别测试
{
公众:
CTest(常量字符*str)
{
printf(“构造函数”\n);
m_str=str;
}
虚拟~CTest()
{
printf(“析构函数”);
}
无效输出()
{
printf(“输出:%s\n”,m_str.c_str());
}
受保护的:
std::字符串m_str;
};
结构TTT
{
煤焦测试[sizeof(CTest)];
};
int main(int argc,char*argv[])
{
struct TTT*TTT=(struct TTT*)malloc(sizeof(struct TTT));
测试*测试=(测试*)(ttt->test\u ptr);
测试->测试测试(“123456”);
测试->输出();
test->~CTest();
返回0;
}
您不能直接调用构造函数。相反,您必须对对象()使用“placement new”。它基本上使用您提供的内存调用构造函数。但是,您可以直接调用析构函数——只需调用~CTest(),而不必调用delete。关于问题的标题
“我可以显式调用类的构造函数和析构函数吗?”
当然可以,例如,每次创建类的临时函数时,您都非常显式地调用构造函数(显式析构函数调用更为罕见)
很长一段时间以来,标准将这个问题与它的即兴评论“看起来像一个显式构造函数调用”混淆在一起,但很简单,显式是显式的,隐式是隐式的,调用是调用,标准没有重新定义这些术语。关于应用于构造函数的术语“调用”,本标准指的是源代码级构造函数“调用”,例如在默认构造函数的定义中。不管怎么说,这是一个术语问题
但真正的问题不同
“我需要使用预分配内存中的类对象”
为此,您可以使用一个分配函数,该函数只返回您传递给它的地址。标准库通过标题
提供了这种分配功能。要选择“虚拟”分配函数,只需将指向缓冲区的指针作为参数传递给它,这样就可以通过普通重载解析来选择它
要传递指针参数,可以使用placement new语法,如下所示:
#include <new>
// ...
CTest* p_test = ::new (&ttt) CTest( "12345" );
#包括
// ...
CTest*p_测试=::新(&ttt)CTest(“12345”);
其中ttt
是缓冲区
请注意全局名称空间限定,通常需要全局名称空间限定,以避免拾取所讨论的类定义的分配函数
为了让它很好地工作—没有崩溃,没有修复延迟—您使用的地址必须与类保持适当的对齐。例如,它可能需要是4的倍数或8的倍数,具体取决于类别。如果缓冲区来自默认的new
,那么没问题,只需使用缓冲区的开头,但我不确定您使用的malloc
请务必查阅相关文档
C++11对对齐有一些支持,但您的编译器可能还不一定提供这种支持。对于特定于平台的代码,您可能不需要解决此问题。然而,如果您想要可移植代码,您应该确保正确对齐
实际上,一种方法是使缓冲区比没有对齐要求的情况下严格需要的大16字节,并使用指针指向与缓冲区开始位置适当偏移的位置。请参阅。“不能直接调用构造函数”是错误的
T()
是直接调用构造函数的一个示例。其中T
是一种类类型。您的意思是T*T=new T()?这仍在通过纽约进行。您没有直接调用构造函数。通过临时调用它也会创建一个新对象。在这种情况下,您也不会对特定对象调用构造函数。不,我的意思不是我写的东西。这包括不,我没有描述如何在现有存储中创建对象。我在回答这个问题时确实描述了这一点。那么,我不知道你为什么认为我的陈述是错误的。无法直接在对象上调用构造函数。如果有,您可以多次调用它。构造函数的要点是,您正在“构造”一个对象——它不是单独调用函数。这是创建对象的一部分。您的语句没有提到“在对象上”。这种背景可能在你的脑海中,但例如,这个问题的标题并不强制这种背景。这是一个声明不明确的问题,因此我没有投反对票谢谢你的帮助!